Skip to content

feat(core): add config validation, defaults, and httpConfig extraction#1157

Merged
abueide merged 8 commits into
masterfrom
tapi/config-and-settings
Mar 23, 2026
Merged

feat(core): add config validation, defaults, and httpConfig extraction#1157
abueide merged 8 commits into
masterfrom
tapi/config-and-settings

Conversation

@abueide
Copy link
Copy Markdown
Contributor

@abueide abueide commented Mar 10, 2026

Summary

  • Add validateRateLimitConfig() and validateBackoffConfig() utilities that clamp config values to safe ranges with logger warnings
  • Add defaultHttpConfig with SDD-compliant defaults (status code overrides: 408/410/429/460→retry, 501/505→drop)
  • Add httpConfig field to SegmentClient with getHttpConfig() accessor
  • Extract and merge httpConfig from CDN response in fetchSettings(), validating and clamping values
  • Deep-merge statusCodeOverrides so server-sent partial overrides extend defaults rather than replacing them
  • Add cross-config validation: maxTotalBackoffDuration >= 2x max(maxBackoffInterval, rateLimitConfig.maxRetryInterval)
  • Fix CDN integrations handling: treat null/missing integrations as empty {} (authoritative "no integrations") rather than falling back to defaultSettings
  • Add test suites for config validation (15 tests) and httpConfig extraction/CDN handling (37 tests)

PR 2 of 5 in the TAPI backoff/retry stack. Depends on #1156.

Test plan

  • All 52 config validation and fetchSettings tests pass
  • Server sending partial statusCodeOverrides: { '501': 'drop' } preserves default overrides for 408, 410, 429, 460, 505
  • validateBackoffConfig cross-checks against rateLimitConfig.maxRetryInterval
  • CDN returning {} or {integrations: null} correctly stores empty integrations (disables SegmentDestination)
  • All core tests pass (429/429)
  • All e2e tests pass (13/13)

🤖 Generated with Claude Code

@abueide abueide force-pushed the tapi/types-and-errors branch from d6f2a89 to 915c8e3 Compare March 12, 2026 14:56
@abueide abueide force-pushed the tapi/config-and-settings branch 3 times, most recently from 7a0b957 to f631f9f Compare March 12, 2026 15:24
@abueide abueide force-pushed the tapi/types-and-errors branch from eedad38 to 36997ac Compare March 12, 2026 16:11
@abueide abueide force-pushed the tapi/config-and-settings branch 5 times, most recently from 04bb992 to 658e649 Compare March 18, 2026 21:14
@abueide abueide force-pushed the tapi/types-and-errors branch 2 times, most recently from 1a577e8 to c451d38 Compare March 18, 2026 22:12
@abueide abueide force-pushed the tapi/config-and-settings branch 3 times, most recently from 3a16620 to f3e71c3 Compare March 19, 2026 16:02
@abueide abueide force-pushed the tapi/types-and-errors branch from b1cd5f5 to ff837e7 Compare March 19, 2026 16:15
@abueide abueide force-pushed the tapi/config-and-settings branch from f3e71c3 to 55221f4 Compare March 19, 2026 16:15
@abueide abueide force-pushed the tapi/types-and-errors branch from ff837e7 to a3ac0e5 Compare March 19, 2026 16:57
@abueide abueide force-pushed the tapi/config-and-settings branch 2 times, most recently from 09d48d7 to a6127cc Compare March 19, 2026 17:56
Base automatically changed from tapi/types-and-errors to master March 19, 2026 18:17
@abueide abueide force-pushed the tapi/config-and-settings branch 2 times, most recently from f76fd78 to e1fb9cd Compare March 19, 2026 18:30
abueide and others added 3 commits March 23, 2026 10:58
Add config validation utilities (validateRateLimitConfig,
validateBackoffConfig), default HTTP config constants, and httpConfig
extraction/merging logic in SegmentClient.fetchSettings().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deep-merge statusCodeOverrides so server-sent partial overrides don't
replace defaults. Add rateLimitConfig parameter to validateBackoffConfig
for the cross-config relational constraint:
maxTotalBackoffDuration >= 2x max(maxBackoffInterval, maxRetryInterval).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… validation

Remove autoFlushOnRetryReady from defaultConfig (redundant with TimerFlushPolicy).
Validate integrations field from CDN response before storing — falls back to
defaultSettings when CDN returns null, array, or non-object integrations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@abueide abueide force-pushed the tapi/config-and-settings branch from e1fb9cd to d0f997b Compare March 23, 2026 15:59
abueide and others added 2 commits March 23, 2026 11:08
retryStrategy was removed from Config type in #1156, but remained in
defaultConfig causing build errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When CDN returns a valid 200 with no integrations field (e.g. {}),
treat it as authoritative "no integrations configured" rather than
falling back to defaultSettings. This ensures SegmentDestination is
correctly disabled when the server has no integrations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
abueide and others added 3 commits March 23, 2026 12:59
Extract complex logic into focused helper methods:
- validateIntegrations(): handles normalization and validation
- extractHttpConfig(): handles merge and validation of httpConfig
- applyDefaultSettings(): consolidates fallback logic

This reduces fetchSettings from 98 lines to ~50 lines and improves
testability by isolating each concern.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Move validateIntegrations and extractHttpConfig from SegmentClient
private methods to exported functions in config-validation.ts.

This keeps analytics.ts slimmer and groups all config-related
validation logic in one place.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@abueide abueide merged commit c545aa5 into master Mar 23, 2026
7 checks passed
@abueide abueide deleted the tapi/config-and-settings branch March 23, 2026 19:00
runway-github Bot added a commit to MetaMask/metamask-mobile that referenced this pull request May 21, 2026
…rror in 2.23.0 cp-7.78.0 (#30463)

## Summary

`@segment/analytics-react-native` 2.23.0 introduced a strict
`validateURL` regex via [PR
#1157](segmentio/analytics-react-native#1157)
that only allows `[a-zA-Z0-9_.-]` in query-param values. The MetaMask
Segment proxy URL encodes the write key as standard base64 in a query
param (`?b=<base64>==`), and the trailing `=` padding characters are
rejected by this regex.

When the URL fails validation `SegmentDestination.getEndpoint()`
silently falls back to `https://api.segment.io/v1/b`. Events reach
Segment's default endpoint but the proxy write key is only valid through
`fn.segmentapis.com`, so they are rejected — causing **no events to
appear in Mixpanel**.

## Change

Added `normalizeProxyUrl` in `platform-adapter.ts` that strips trailing
`=` padding from query-param values before passing the URL to the
Segment client config.

- Stripping base64 padding is safe: decoders infer it from data length
and the proxy server accepts both forms.
- The `=` key–value separator is preserved (the regex uses a lookahead
`(?=&|$)` to match only padding at the end of a param value).
- Contains a `TODO` to remove once upstream fixes the regex to accept
all RFC 3986 query characters.

## Test plan

- [ ] Run the app in dev mode and verify analytics events appear in
Mixpanel
- [ ] Verify no "Invalid URL has been passed" errors in the console
- [ ] Run unit tests: `yarn jest platform-adapter`


Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes how the Segment client is configured
and could affect where analytics events are sent if the proxy URL is
altered incorrectly, though the change is narrowly scoped and covered by
unit tests.
> 
> **Overview**
> Fixes Segment proxy URL validation failures by normalizing
`SEGMENT_PROXY_URL` before passing it to `createClient`, stripping
trailing base64 `=` padding from query-param values (while preserving
key/value separators).
> 
> Adds focused unit coverage for `normalizeProxyUrl` across common URL
shapes (single/double padding, multi-param URLs) and a wiring test to
ensure `createPlatformAdapter` passes the normalized `proxy` value into
Segment client configuration.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ee00a41. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: João Santos <joaosantos15@users.noreply.github.com>
runway-github Bot added a commit to MetaMask/metamask-mobile that referenced this pull request May 21, 2026
…rror in 2.23.0 cp-7.78.0 (#30463)

## Summary

`@segment/analytics-react-native` 2.23.0 introduced a strict
`validateURL` regex via [PR
#1157](segmentio/analytics-react-native#1157)
that only allows `[a-zA-Z0-9_.-]` in query-param values. The MetaMask
Segment proxy URL encodes the write key as standard base64 in a query
param (`?b=<base64>==`), and the trailing `=` padding characters are
rejected by this regex.

When the URL fails validation `SegmentDestination.getEndpoint()`
silently falls back to `https://api.segment.io/v1/b`. Events reach
Segment's default endpoint but the proxy write key is only valid through
`fn.segmentapis.com`, so they are rejected — causing **no events to
appear in Mixpanel**.

## Change

Added `normalizeProxyUrl` in `platform-adapter.ts` that strips trailing
`=` padding from query-param values before passing the URL to the
Segment client config.

- Stripping base64 padding is safe: decoders infer it from data length
and the proxy server accepts both forms.
- The `=` key–value separator is preserved (the regex uses a lookahead
`(?=&|$)` to match only padding at the end of a param value).
- Contains a `TODO` to remove once upstream fixes the regex to accept
all RFC 3986 query characters.

## Test plan

- [ ] Run the app in dev mode and verify analytics events appear in
Mixpanel
- [ ] Verify no "Invalid URL has been passed" errors in the console
- [ ] Run unit tests: `yarn jest platform-adapter`

Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes how the Segment client is configured
and could affect where analytics events are sent if the proxy URL is
altered incorrectly, though the change is narrowly scoped and covered by
unit tests.
>
> **Overview**
> Fixes Segment proxy URL validation failures by normalizing
`SEGMENT_PROXY_URL` before passing it to `createClient`, stripping
trailing base64 `=` padding from query-param values (while preserving
key/value separators).
>
> Adds focused unit coverage for `normalizeProxyUrl` across common URL
shapes (single/double padding, multi-param URLs) and a wiring test to
ensure `createPlatformAdapter` passes the normalized `proxy` value into
Segment client configuration.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ee00a41. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: João Santos <joaosantos15@users.noreply.github.com>
runway-github Bot pushed a commit to MetaMask/metamask-mobile that referenced this pull request May 21, 2026
…L to fix invalid-URL error in 2.23.0 cp-7.78.0 (#30463)

## Summary

`@segment/analytics-react-native` 2.23.0 introduced a strict
`validateURL` regex via [PR
#1157](segmentio/analytics-react-native#1157)
that only allows `[a-zA-Z0-9_.-]` in query-param values. The MetaMask
Segment proxy URL encodes the write key as standard base64 in a query
param (`?b=<base64>==`), and the trailing `=` padding characters are
rejected by this regex.

When the URL fails validation `SegmentDestination.getEndpoint()`
silently falls back to `https://api.segment.io/v1/b`. Events reach
Segment's default endpoint but the proxy write key is only valid through
`fn.segmentapis.com`, so they are rejected — causing **no events to
appear in Mixpanel**.

## Change

Added `normalizeProxyUrl` in `platform-adapter.ts` that strips trailing
`=` padding from query-param values before passing the URL to the
Segment client config.

- Stripping base64 padding is safe: decoders infer it from data length
and the proxy server accepts both forms.
- The `=` key–value separator is preserved (the regex uses a lookahead
`(?=&|$)` to match only padding at the end of a param value).
- Contains a `TODO` to remove once upstream fixes the regex to accept
all RFC 3986 query characters.

## Test plan

- [ ] Run the app in dev mode and verify analytics events appear in
Mixpanel
- [ ] Verify no "Invalid URL has been passed" errors in the console
- [ ] Run unit tests: `yarn jest platform-adapter`


Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes how the Segment client is configured
and could affect where analytics events are sent if the proxy URL is
altered incorrectly, though the change is narrowly scoped and covered by
unit tests.
> 
> **Overview**
> Fixes Segment proxy URL validation failures by normalizing
`SEGMENT_PROXY_URL` before passing it to `createClient`, stripping
trailing base64 `=` padding from query-param values (while preserving
key/value separators).
> 
> Adds focused unit coverage for `normalizeProxyUrl` across common URL
shapes (single/double padding, multi-param URLs) and a wiring test to
ensure `createPlatformAdapter` passes the normalized `proxy` value into
Segment client configuration.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ee00a41. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: João Santos <joaosantos15@users.noreply.github.com>
runway-github Bot added a commit to MetaMask/metamask-mobile that referenced this pull request May 21, 2026
…rror in 2.23.0 cp-7.78.0 (#30463)

## Summary

`@segment/analytics-react-native` 2.23.0 introduced a strict
`validateURL` regex via [PR
#1157](segmentio/analytics-react-native#1157)
that only allows `[a-zA-Z0-9_.-]` in query-param values. The MetaMask
Segment proxy URL encodes the write key as standard base64 in a query
param (`?b=<base64>==`), and the trailing `=` padding characters are
rejected by this regex.

When the URL fails validation `SegmentDestination.getEndpoint()`
silently falls back to `https://api.segment.io/v1/b`. Events reach
Segment's default endpoint but the proxy write key is only valid through
`fn.segmentapis.com`, so they are rejected — causing **no events to
appear in Mixpanel**.

## Change

Added `normalizeProxyUrl` in `platform-adapter.ts` that strips trailing
`=` padding from query-param values before passing the URL to the
Segment client config.

- Stripping base64 padding is safe: decoders infer it from data length
and the proxy server accepts both forms.
- The `=` key–value separator is preserved (the regex uses a lookahead
`(?=&|$)` to match only padding at the end of a param value).
- Contains a `TODO` to remove once upstream fixes the regex to accept
all RFC 3986 query characters.

## Test plan

- [ ] Run the app in dev mode and verify analytics events appear in
Mixpanel
- [ ] Verify no "Invalid URL has been passed" errors in the console
- [ ] Run unit tests: `yarn jest platform-adapter`


Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes how the Segment client is configured
and could affect where analytics events are sent if the proxy URL is
altered incorrectly, though the change is narrowly scoped and covered by
unit tests.
> 
> **Overview**
> Fixes Segment proxy URL validation failures by normalizing
`SEGMENT_PROXY_URL` before passing it to `createClient`, stripping
trailing base64 `=` padding from query-param values (while preserving
key/value separators).
> 
> Adds focused unit coverage for `normalizeProxyUrl` across common URL
shapes (single/double padding, multi-param URLs) and a wiring test to
ensure `createPlatformAdapter` passes the normalized `proxy` value into
Segment client configuration.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ee00a41. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: João Santos <joaosantos15@users.noreply.github.com>
runway-github Bot added a commit to MetaMask/metamask-mobile that referenced this pull request May 21, 2026
…rror in 2.23.0 cp-7.78.0 (#30463)

## Summary

`@segment/analytics-react-native` 2.23.0 introduced a strict
`validateURL` regex via [PR
#1157](segmentio/analytics-react-native#1157)
that only allows `[a-zA-Z0-9_.-]` in query-param values. The MetaMask
Segment proxy URL encodes the write key as standard base64 in a query
param (`?b=<base64>==`), and the trailing `=` padding characters are
rejected by this regex.

When the URL fails validation `SegmentDestination.getEndpoint()`
silently falls back to `https://api.segment.io/v1/b`. Events reach
Segment's default endpoint but the proxy write key is only valid through
`fn.segmentapis.com`, so they are rejected — causing **no events to
appear in Mixpanel**.

## Change

Added `normalizeProxyUrl` in `platform-adapter.ts` that strips trailing
`=` padding from query-param values before passing the URL to the
Segment client config.

- Stripping base64 padding is safe: decoders infer it from data length
and the proxy server accepts both forms.
- The `=` key–value separator is preserved (the regex uses a lookahead
`(?=&|$)` to match only padding at the end of a param value).
- Contains a `TODO` to remove once upstream fixes the regex to accept
all RFC 3986 query characters.

## Test plan

- [ ] Run the app in dev mode and verify analytics events appear in
Mixpanel
- [ ] Verify no "Invalid URL has been passed" errors in the console
- [ ] Run unit tests: `yarn jest platform-adapter`

Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes how the Segment client is configured
and could affect where analytics events are sent if the proxy URL is
altered incorrectly, though the change is narrowly scoped and covered by
unit tests.
>
> **Overview**
> Fixes Segment proxy URL validation failures by normalizing
`SEGMENT_PROXY_URL` before passing it to `createClient`, stripping
trailing base64 `=` padding from query-param values (while preserving
key/value separators).
>
> Adds focused unit coverage for `normalizeProxyUrl` across common URL
shapes (single/double padding, multi-param URLs) and a wiring test to
ensure `createPlatformAdapter` passes the normalized `proxy` value into
Segment client configuration.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ee00a41. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: João Santos <joaosantos15@users.noreply.github.com>
runway-github Bot pushed a commit to MetaMask/metamask-mobile that referenced this pull request May 21, 2026
…in 2.23.0 cp-7.78.0 (#30463)

## Summary

`@segment/analytics-react-native` 2.23.0 introduced a strict
`validateURL` regex via [PR
#1157](segmentio/analytics-react-native#1157)
that only allows `[a-zA-Z0-9_.-]` in query-param values. The MetaMask
Segment proxy URL encodes the write key as standard base64 in a query
param (`?b=<base64>==`), and the trailing `=` padding characters are
rejected by this regex.

When the URL fails validation `SegmentDestination.getEndpoint()`
silently falls back to `https://api.segment.io/v1/b`. Events reach
Segment's default endpoint but the proxy write key is only valid through
`fn.segmentapis.com`, so they are rejected — causing **no events to
appear in Mixpanel**.

## Change

Added `normalizeProxyUrl` in `platform-adapter.ts` that strips trailing
`=` padding from query-param values before passing the URL to the
Segment client config.

- Stripping base64 padding is safe: decoders infer it from data length
and the proxy server accepts both forms.
- The `=` key–value separator is preserved (the regex uses a lookahead
`(?=&|$)` to match only padding at the end of a param value).
- Contains a `TODO` to remove once upstream fixes the regex to accept
all RFC 3986 query characters.

## Test plan

- [ ] Run the app in dev mode and verify analytics events appear in
Mixpanel
- [ ] Verify no "Invalid URL has been passed" errors in the console
- [ ] Run unit tests: `yarn jest platform-adapter`


Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes how the Segment client is configured
and could affect where analytics events are sent if the proxy URL is
altered incorrectly, though the change is narrowly scoped and covered by
unit tests.
> 
> **Overview**
> Fixes Segment proxy URL validation failures by normalizing
`SEGMENT_PROXY_URL` before passing it to `createClient`, stripping
trailing base64 `=` padding from query-param values (while preserving
key/value separators).
> 
> Adds focused unit coverage for `normalizeProxyUrl` across common URL
shapes (single/double padding, multi-param URLs) and a wiring test to
ensure `createPlatformAdapter` passes the normalized `proxy` value into
Segment client configuration.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ee00a41. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: João Santos <joaosantos15@users.noreply.github.com>
pull Bot pushed a commit to Dustin4444/metamask-mobile that referenced this pull request May 21, 2026
…in 2.23.0 cp-7.78.0 (MetaMask#30463)

## Summary

`@segment/analytics-react-native` 2.23.0 introduced a strict
`validateURL` regex via [PR
MetaMask#1157](segmentio/analytics-react-native#1157)
that only allows `[a-zA-Z0-9_.-]` in query-param values. The MetaMask
Segment proxy URL encodes the write key as standard base64 in a query
param (`?b=<base64>==`), and the trailing `=` padding characters are
rejected by this regex.

When the URL fails validation `SegmentDestination.getEndpoint()`
silently falls back to `https://api.segment.io/v1/b`. Events reach
Segment's default endpoint but the proxy write key is only valid through
`fn.segmentapis.com`, so they are rejected — causing **no events to
appear in Mixpanel**.

## Change

Added `normalizeProxyUrl` in `platform-adapter.ts` that strips trailing
`=` padding from query-param values before passing the URL to the
Segment client config.

- Stripping base64 padding is safe: decoders infer it from data length
and the proxy server accepts both forms.
- The `=` key–value separator is preserved (the regex uses a lookahead
`(?=&|$)` to match only padding at the end of a param value).
- Contains a `TODO` to remove once upstream fixes the regex to accept
all RFC 3986 query characters.

## Test plan

- [ ] Run the app in dev mode and verify analytics events appear in
Mixpanel
- [ ] Verify no "Invalid URL has been passed" errors in the console
- [ ] Run unit tests: `yarn jest platform-adapter`


Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes how the Segment client is configured
and could affect where analytics events are sent if the proxy URL is
altered incorrectly, though the change is narrowly scoped and covered by
unit tests.
> 
> **Overview**
> Fixes Segment proxy URL validation failures by normalizing
`SEGMENT_PROXY_URL` before passing it to `createClient`, stripping
trailing base64 `=` padding from query-param values (while preserving
key/value separators).
> 
> Adds focused unit coverage for `normalizeProxyUrl` across common URL
shapes (single/double padding, multi-param URLs) and a wiring test to
ensure `createPlatformAdapter` passes the normalized `proxy` value into
Segment client configuration.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ee00a41. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: João Santos <joaosantos15@users.noreply.github.com>
vpintorico pushed a commit to MetaMask/metamask-mobile that referenced this pull request May 21, 2026
…L to fix invalid-URL error in 2.23.0 cp-7.78.0 (#30496)

- fix(analytics): normalise Segment proxy URL to fix invalid-URL error
in 2.23.0 cp-7.78.0 (#30463)

## Summary

`@segment/analytics-react-native` 2.23.0 introduced a strict
`validateURL` regex via [PR
#1157](segmentio/analytics-react-native#1157)
that only allows `[a-zA-Z0-9_.-]` in query-param values. The MetaMask
Segment proxy URL encodes the write key as standard base64 in a query
param (`?b=<base64>==`), and the trailing `=` padding characters are
rejected by this regex.

When the URL fails validation `SegmentDestination.getEndpoint()`
silently falls back to `https://api.segment.io/v1/b`. Events reach
Segment's default endpoint but the proxy write key is only valid through
`fn.segmentapis.com`, so they are rejected — causing **no events to
appear in Mixpanel**.

## Change

Added `normalizeProxyUrl` in `platform-adapter.ts` that strips trailing
`=` padding from query-param values before passing the URL to the
Segment client config.

- Stripping base64 padding is safe: decoders infer it from data length
and the proxy server accepts both forms.
- The `=` key–value separator is preserved (the regex uses a lookahead
`(?=&|$)` to match only padding at the end of a param value).
- Contains a `TODO` to remove once upstream fixes the regex to accept
all RFC 3986 query characters.

## Test plan

- [ ] Run the app in dev mode and verify analytics events appear in
Mixpanel
- [ ] Verify no "Invalid URL has been passed" errors in the console
- [ ] Run unit tests: `yarn jest platform-adapter`


Made with [Cursor](https://cursor.com)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Moderate risk because it changes how the Segment client is configured
and could affect where analytics events are sent if the proxy URL is
altered incorrectly, though the change is narrowly scoped and covered by
unit tests.
> 
> **Overview**
> Fixes Segment proxy URL validation failures by normalizing
`SEGMENT_PROXY_URL` before passing it to `createClient`, stripping
trailing base64 `=` padding from query-param values (while preserving
key/value separators).
> 
> Adds focused unit coverage for `normalizeProxyUrl` across common URL
shapes (single/double padding, multi-param URLs) and a wiring test to
ensure `createPlatformAdapter` passes the normalized `proxy` value into
Segment client configuration.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ee00a41. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: João Santos <joaosantos15@users.noreply.github.com>
[66f0cb2](66f0cb2)

Co-authored-by: tommasini <46944231+tommasini@users.noreply.github.com>
Co-authored-by: João Santos <joaosantos15@users.noreply.github.com>
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