Skip to content

feat: [MM-69203] Implement collection, storage and attachment of session attributes - #171

Merged
devinbinnie merged 3 commits into
masterfrom
MM-69203
Aug 11, 2026
Merged

feat: [MM-69203] Implement collection, storage and attachment of session attributes#171
devinbinnie merged 3 commits into
masterfrom
MM-69203

Conversation

@devinbinnie

Copy link
Copy Markdown
Member

Summary

DRAFT: Implement collection, storage and attachment of session attributes

Ticket Link

https://mattermost.atlassian.net/browse/MM-69203

@devinbinnie
devinbinnie requested review from enahum and larkox July 17, 2026 16:01
Comment thread android/src/main/java/com/mattermost/networkclient/ApiClientModuleImpl.kt Outdated
Comment thread package.json Outdated
Comment thread android/src/main/java/com/mattermost/networkclient/NetworkClient.kt Outdated
Comment thread ios/patches/apply_patches.rb Outdated
Comment thread ios/SessionAttributes/SessionAttributes.swift Outdated
Comment thread ios/NetworkClient.swift Outdated
Comment thread react-native-network-client.podspec
@devinbinnie
devinbinnie requested a review from enahum August 10, 2026 18:02

@enahum enahum left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yay!!

return null
}

private fun getSessionAttributesInterceptor(options: ReadableMap?): SessionAttributesInterceptor? {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nice

@devinbinnie
devinbinnie marked this pull request as ready for review August 11, 2026 12:26
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This change adds session-attribute APIs, native persistence, device and network collection, TTL-based header generation, and authenticated request integration for Android and iOS. React Native exposes configuration methods and header retrieval.

Changes

Session attributes

Layer / File(s) Summary
Public APIs and native-module wiring
src/APIClient/NativeApiClient.ts, src/SessionAttributes/index.tsx, src/types/APIClient.ts, src/schemas.tsx, src/index.tsx, android/src/newarch/..., android/src/oldarch/..., android/src/main/.../ApiClientModuleImpl.kt, ios/ApiClient/..., react-native-network-client.podspec
React Native, Android, and iOS APIs now configure session attributes and retrieve outbound headers. The podspec separates the React-free SessionAttributes subspec from Core.
Persistent state and header generation
android/src/main/.../sessionattributes/SessionAttributesStore.kt, android/src/main/.../sessionattributes/SessionAttributesEngine.kt, ios/SessionAttributes/SessionAttributesStore.swift, ios/SessionAttributes/SessionAttributesEngine.swift, android/src/main/.../SessionAttributesConstants.kt, ios/SessionAttributes/SessionAttributesConstants.swift
Native engines manage enabled servers, manifests, fields, stable values, TTL timestamps, and Base64-encoded JSON headers. Android uses encrypted DataStore. iOS uses serialized UserDefaults state.
Device and network attribute collection
android/src/main/.../SessionAttributesCollector.kt, ios/SessionAttributes/SessionAttributesCollector.swift, android/src/main/.../SessionAttributes.kt, ios/SessionAttributes/SessionAttributes.swift
Collectors resolve stable values and live device, network, VPN, SSID, MDM, and server FQDN attributes. Native facades expose header lookup and initialization.
Authenticated request header integration
android/src/main/.../NetworkClient.kt, android/src/main/.../interceptors/SessionAttributesInterceptor.kt, ios/NetworkClient.swift, ios/Adapters/SessionAttributesAdapter.swift
Request pipelines add session-attribute headers after bearer authentication when enabled. Existing headers, unauthorised requests, and unavailable values remain unchanged.
Behavioural validation
test-runner/src/test/kotlin/com/mattermost/networkclient/SessionAttributesTest.kt
Tests cover TTL decisions, network transport precedence, header injection guards, null values, cache operations, removals, and server isolation.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReactNative
  participant ApiClientWrapper
  participant SessionAttributesEngine
  participant SessionAttributesStore
  participant SessionAttributesCollector
  participant NetworkClient

  ReactNative->>ApiClientWrapper: Configure server manifest and fields
  ApiClientWrapper->>SessionAttributesEngine: Store session-attribute configuration
  SessionAttributesEngine->>SessionAttributesStore: Persist server state
  NetworkClient->>SessionAttributesEngine: Request outbound header
  SessionAttributesEngine->>SessionAttributesStore: Load enabled state and TTL timestamps
  SessionAttributesEngine->>SessionAttributesCollector: Collect eligible values
  SessionAttributesCollector-->>SessionAttributesEngine: Return attribute values
  SessionAttributesEngine-->>NetworkClient: Return Base64-encoded header
  NetworkClient-->>ReactNative: Send authenticated request with session header
``

</details>

<!-- walkthrough_end -->
<!-- pre_merge_checks_walkthrough_start -->

<details>
<summary>🚥 Pre-merge checks | ✅ 4 | ❌ 1</summary>

### ❌ Failed checks (1 warning)

|     Check name     | Status     | Explanation                                                                          | Resolution                                                                         |
| :----------------: | :--------- | :----------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------- |
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 5.22% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |

<details>
<summary>✅ Passed checks (4 passed)</summary>

|         Check name         | Status   | Explanation                                                                                                   |
| :------------------------: | :------- | :------------------------------------------------------------------------------------------------------------ |
|         Title check        | ✅ Passed | The title clearly summarizes the implementation of session-attribute collection, storage, and attachment.     |
|      Description check     | ✅ Passed | The description directly relates to the session-attributes implementation and includes the associated ticket. |
|     Linked Issues check    | ✅ Passed | Check skipped because no linked issues were found for this pull request.                                      |
| Out of Scope Changes check | ✅ Passed | Check skipped because no linked issues were found for this pull request.                                      |

</details>

</details>

<!-- pre_merge_checks_walkthrough_end -->
<!-- finishing_touch_checkbox_start -->

<details>
<summary>✨ Finishing Touches 💡 1</summary>

<!-- finishing_touch_suggestion:docstrings -->
<details>
<summary>📝 Generate docstrings 💡</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId": "3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch

</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>

- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Commit unit tests in branch `MM-69203`

</details>

</details>

<!-- finishing_touch_checkbox_end -->
<!-- This is an auto-generated comment: all tool run failures by coderabbit.ai -->

> [!WARNING]
> There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.
> 
> <details>
> <summary>🔧 ESLint</summary>
> 
> > If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.
> 
> ESLint install failed: dependency version conflict. Check your lock file or package.json.
> 
> 
> 
> </details>

<!-- end of auto-generated comment: all tool run failures by coderabbit.ai -->
<!-- tips_start -->

---




<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>

<!-- tips_end -->
Loading

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 13

🧹 Nitpick comments (6)
ios/SessionAttributes/SessionAttributesCollector.swift (2)

28-55: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoff

The NWPathMonitor runs for the process lifetime, even when no server enables session attributes.

SessionAttributesCollector.shared starts pathMonitor in init. The singleton is created the first time any code touches SessionAttributesEngine.shared, and SessionAttributesEngine holds collector as a stored property. The monitor then runs continuously, and each Wi-Fi path update triggers NEHotspotNetwork.fetchCurrent, which can present a location-permission requirement.

Start the monitor lazily, when the first server enables session attributes, and stop it when no server has the feature enabled.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ios/SessionAttributes/SessionAttributesCollector.swift` around lines 28 - 55,
Update SessionAttributesCollector initialization so it does not start
pathMonitor automatically. Add lifecycle methods to start the monitor when the
first server enables session attributes and cancel it when the last enabled
server is removed, ensuring SessionAttributesEngine or
SessionAttributesCollector only manages monitoring while the feature is in use.

138-159: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the unreachable pre-iOS 14 SSID path.

The podspec and example app target iOS 15.1. Remove resolveLegacySsid() and the unused SystemConfiguration.CaptiveNetwork import.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ios/SessionAttributes/SessionAttributesCollector.swift` around lines 138 -
159, Remove the pre-iOS 14 fallback from the SSID collection method, including
the `resolveLegacySsid()` call and its helper implementation. Delete the
now-unused `SystemConfiguration.CaptiveNetwork` import, while preserving the iOS
14+ `NEHotspotNetwork.fetchCurrent` behavior.
android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesCollector.kt (1)

44-53: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

getServerFqdn caches the empty failure result permanently.

computeIfAbsent stores the mapping function result, including "". After one parse failure, the cache returns "" for that server for the process lifetime, and no retry occurs. Uri.parse is deterministic, so a retry rarely changes the outcome, but the cache also never bounds its size across server URLs.

Skip caching the empty result.

♻️ Proposed change
     private fun getServerFqdn(serverUrl: String): String {
-        return fqdnCache.computeIfAbsent(serverUrl) { url ->
-            try {
-                Uri.parse(url).host ?: ""
-            } catch (e: Exception) {
-                Log.w("NetworkClient", "Failed to resolve server FQDN: ${e.message}")
-                ""
-            }
-        }
+        fqdnCache[serverUrl]?.let { return it }
+        val host = try {
+            Uri.parse(serverUrl).host ?: ""
+        } catch (e: Exception) {
+            Log.w("NetworkClient", "Failed to resolve server FQDN: ${e.message}")
+            ""
+        }
+        if (host.isNotEmpty()) {
+            fqdnCache[serverUrl] = host
+        }
+        return host
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesCollector.kt`
around lines 44 - 53, Update getServerFqdn so only non-empty parsed host values
are stored in fqdnCache; parse failures and empty hosts must return "" without
creating a cache entry, allowing subsequent calls to retry while preserving the
existing warning behavior.
ios/SessionAttributes/SessionAttributesStore.swift (1)

95-108: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

upsertField and removeField fail silently when no state exists.

Both methods return without action when readState returns nil or when state.enabled is false. The JS caller receives no signal. A caller that invokes upsertSessionAttributesField before setSessionAttributesEnabled or setSessionAttributesManifest sees the field silently dropped.

The methods are synchronous and return void, so an error return is not available. Add a log statement so the drop is observable during debugging.

Also applies to: 110-119

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ios/SessionAttributes/SessionAttributesStore.swift` around lines 95 - 108,
Update upsertField and removeField to log when readState(for:) returns nil or
the retrieved state is disabled before returning, while preserving their
synchronous void behavior and existing state-update logic. Include the serverUrl
and field identifier where available so silently dropped operations are
observable during debugging.
test-runner/src/test/kotlin/com/mattermost/networkclient/SessionAttributesTest.kt (1)

28-45: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding coverage for the header payload construction.

The inline reproductions are intentional for the pure-JVM runner. Based on learnings, the test-runner module must not reference production classes that transitively depend on com.facebook.react.bridge.

The current tests cover the TTL predicate, the transport mapping, the interceptor guard, and the cache. Three behaviours from SessionAttributesEngine.getOutboundHeader have no coverage:

  1. A field whose collected value is empty is skipped and its lastSentAt is not updated.
  2. An empty payload produces no header at all.
  3. The payload is JSON, then base64 encoded.

Add inline reproductions of those three rules so a regression in the production ordering is visible.

Based on learnings: in the test-runner module (pure JVM/Kotlin, with no Android SDK and no React Native dependencies), it is intentional to duplicate the relevant logic so the test can validate behaviour in isolation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@test-runner/src/test/kotlin/com/mattermost/networkclient/SessionAttributesTest.kt`
around lines 28 - 45, Add pure-JVM test coverage alongside the existing helpers
shouldSend and interfaceType by reproducing getOutboundHeader’s relevant
behavior: skip fields with empty collected values without updating lastSentAt,
return no header for an entirely empty payload, and serialize non-empty payloads
as JSON before Base64 encoding. Keep the reproduction inline and independent of
production classes or React Native dependencies.

Source: Learnings

android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesStore.kt (1)

197-216: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

setStableValues can leave the cache and the persisted value out of order.

setStableValues assigns stableValues under cacheLock and then calls persist under persistLock. The two locks are independent. If two threads call setStableValues concurrently, thread A can win the cache assignment while thread B wins the persist order. The in-memory value then differs from the stored value, and the difference survives a process restart.

Hold persistLock for the cache assignment and the write together, or build the JSON and update the cache inside the same critical section that orders the write.

♻️ Proposed fix to order the cache update with the write
 fun setStableValues(values: Map<String, String>) {
     val json = JSONObject()
     values.forEach { (key, value) -> json.put(key, value) }
-    synchronized(cacheLock) {
-        stableValues = values.toMap()
-    }
-    persist(SessionAttributesConstants.STABLE_VALUES_ALIAS, json.toString())
+    synchronized(persistLock) {
+        synchronized(cacheLock) {
+            stableValues = values.toMap()
+        }
+        persistLocked(SessionAttributesConstants.STABLE_VALUES_ALIAS, json.toString())
+    }
 }

Extract the body of persist into a persistLocked helper that assumes the caller holds persistLock, and keep persist as the wrapper that takes the lock.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesStore.kt`
around lines 197 - 216, Update setStableValues so cache assignment and
persistence are ordered under the same persistLock critical section. Extract
persist’s write logic into a persistLocked helper that assumes persistLock is
held, retain persist as the locking wrapper, and invoke persistLocked after
updating stableValues while holding persistLock.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesCollector.kt`:
- Around line 108-126: Update resolveIpAddress to skip interfaces that are down
or virtual before inspecting their addresses, and retain only non-loopback IPv4
candidates. Align the selection with the iOS collector’s physical-interface
behavior where possible, while preserving the existing empty-string fallback and
warning handling.
- Around line 87-106: Update currentNetworkSnapshot to use a safe
ConnectivityManager lookup and guard the network inspection and address/SSID
collection so any failure returns an empty NetworkSnapshot without propagating
into the interceptor. Apply the same failure-safe handling to isMdmEnrolled,
including its system-service and applicationRestrictions access, while
preserving normal results when collection succeeds.
- Around line 29-42: Update SessionAttributesEngine.getOutboundHeader to compute
currentNetworkSnapshot once and pass it into SessionAttributesCollector.collect
for each manifest field. Change collect to accept and reuse that snapshot only
for network attributes, while avoiding snapshot creation for stable values,
MDM_ENROLLED, SERVER_FQDN, and unknown names.

In
`@android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesEngine.kt`:
- Around line 77-115: Make the read, TTL decision, timestamp update, and
persistence in getOutboundHeader atomic per serverUrl, using synchronization or
a store-side operation protected by cacheLock. Prefer a SessionAttributesStore
API such as claimDueFields that atomically identifies due fields without
replacing manifest, then collect values and stamp only fields with non-empty
values; ensure concurrent requests cannot emit the same field within its TTL or
overwrite manifest changes.

In `@ios/SessionAttributes/SessionAttributesCollector.swift`:
- Around line 197-226: Update resolveIpAddress to return the first valid
non-loopback IPv4 address from the interface list instead of overwriting it with
later en0/en1 matches; include other active interfaces as needed to match the
Android client_ip_address behavior, and confirm or preserve the intended iOS
platform scope if broader interface support is not acceptable.
- Around line 197-226: The client_ip_address collectors use inconsistent
interface-selection rules. In
ios/SessionAttributes/SessionAttributesCollector.swift:197-226, define the
shared accepted-interface rule, select the first matching non-zero IPv4 address,
and stop scanning after it is found instead of retaining the last match; in
android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesCollector.kt:108-126,
apply that same interface filter to the existing first-address lookup, excluding
other, VPN, and virtual interfaces.
- Line 20: Synchronize all reads and writes to fqdnCache within
SessionAttributesCollector.getServerFqdn using the existing monitorQueue. Ensure
cache lookup, updates at both write sites, and the returned value execute within
the same serialized access path, preserving the current FQDN resolution
behavior.
- Around line 208-218: Update the IPv4 address handling in the interface
collection logic to reinterpret ifa_addr as sockaddr_in and pass its sin_addr to
inet_ntop instead of the sockaddr header. Preserve the existing en0/en1
filtering and non-zero IP assignment behavior.

In `@ios/SessionAttributes/SessionAttributesEngine.swift`:
- Around line 56-94: Make the read-compute-write sequence in getOutboundHeader
atomic by adding and using a serialized mutateState helper on
SessionAttributesStore. Build the payload and update lastSentAt inside the
mutation closure, persist the state only when a payload is produced, and
preserve the existing nil behavior for disabled, empty, or unchanged state while
ensuring concurrent requests cannot lose timestamp updates.
- Around line 111-119: Update getOutboundHeader to apply the parsed
grace_period_seconds value from SAField when determining outbound session
behavior, preserving the TypeScript contract’s grace-period semantics;
alternatively, remove grace_period_seconds consistently from the cross-platform
contract and related parser/model usage.

In `@ios/SessionAttributes/SessionAttributesStore.swift`:
- Around line 26-29: Replace the UserDefaults-backed persistence in
SessionAttributesStore, including the app-group selection in init(), with
encrypted storage such as the existing iOS Keychain or encrypted-storage helper.
Ensure stable values and session attributes including client_ip_address, ssid,
and client_device_id are written to and read from that encrypted backend,
preserving the current store API and app-group behavior where applicable.
- Around line 31-35: Update serverKey(_:) to canonicalize the URL consistently
before hashing: lowercase only its scheme and host while preserving the path’s
case, then apply the same normalization for both public state updates and
request lookups using their URL string sources. Keep the resulting SHA256 key
generation unchanged.

In `@src/APIClient/NativeApiClient.ts`:
- Around line 170-176: The synchronous getSessionAttributesHeader API must
return the codegen-supported nullable type string | null and must not perform
storage, network, device-attribute collection, or synchronous queue work on the
JS thread. Update the native getter and its implementation to return precomputed
or cached data (or provide an asynchronous path), while preserving any public
wrapper conversion from null to undefined.

---

Nitpick comments:
In
`@android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesCollector.kt`:
- Around line 44-53: Update getServerFqdn so only non-empty parsed host values
are stored in fqdnCache; parse failures and empty hosts must return "" without
creating a cache entry, allowing subsequent calls to retry while preserving the
existing warning behavior.

In
`@android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesStore.kt`:
- Around line 197-216: Update setStableValues so cache assignment and
persistence are ordered under the same persistLock critical section. Extract
persist’s write logic into a persistLocked helper that assumes persistLock is
held, retain persist as the locking wrapper, and invoke persistLocked after
updating stableValues while holding persistLock.

In `@ios/SessionAttributes/SessionAttributesCollector.swift`:
- Around line 28-55: Update SessionAttributesCollector initialization so it does
not start pathMonitor automatically. Add lifecycle methods to start the monitor
when the first server enables session attributes and cancel it when the last
enabled server is removed, ensuring SessionAttributesEngine or
SessionAttributesCollector only manages monitoring while the feature is in use.
- Around line 138-159: Remove the pre-iOS 14 fallback from the SSID collection
method, including the `resolveLegacySsid()` call and its helper implementation.
Delete the now-unused `SystemConfiguration.CaptiveNetwork` import, while
preserving the iOS 14+ `NEHotspotNetwork.fetchCurrent` behavior.

In `@ios/SessionAttributes/SessionAttributesStore.swift`:
- Around line 95-108: Update upsertField and removeField to log when
readState(for:) returns nil or the retrieved state is disabled before returning,
while preserving their synchronous void behavior and existing state-update
logic. Include the serverUrl and field identifier where available so silently
dropped operations are observable during debugging.

In
`@test-runner/src/test/kotlin/com/mattermost/networkclient/SessionAttributesTest.kt`:
- Around line 28-45: Add pure-JVM test coverage alongside the existing helpers
shouldSend and interfaceType by reproducing getOutboundHeader’s relevant
behavior: skip fields with empty collected values without updating lastSentAt,
return no header for an entirely empty payload, and serialize non-empty payloads
as JSON before Base64 encoding. Keep the reproduction inline and independent of
production classes or React Native dependencies.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8b0372f0-b4cb-410f-b8c3-9cdec683b7c6

📥 Commits

Reviewing files that changed from the base of the PR and between de45de9 and 9734d70.

📒 Files selected for processing (26)
  • android/src/main/java/com/mattermost/networkclient/ApiClientModuleImpl.kt
  • android/src/main/java/com/mattermost/networkclient/NetworkClient.kt
  • android/src/main/java/com/mattermost/networkclient/interceptors/SessionAttributesInterceptor.kt
  • android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributes.kt
  • android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesCollector.kt
  • android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesConstants.kt
  • android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesEngine.kt
  • android/src/main/java/com/mattermost/networkclient/sessionattributes/SessionAttributesStore.kt
  • android/src/newarch/java/com/ApiClientModule.kt
  • android/src/oldarch/java/com/ApiClientModule.kt
  • ios/Adapters/SessionAttributesAdapter.swift
  • ios/ApiClient/ApiClient.mm
  • ios/ApiClient/ApiClientWrapper.swift
  • ios/NetworkClient.swift
  • ios/SessionAttributes/SessionAttributes.swift
  • ios/SessionAttributes/SessionAttributesCollector.swift
  • ios/SessionAttributes/SessionAttributesConstants.swift
  • ios/SessionAttributes/SessionAttributesEngine.swift
  • ios/SessionAttributes/SessionAttributesStore.swift
  • react-native-network-client.podspec
  • src/APIClient/NativeApiClient.ts
  • src/SessionAttributes/index.tsx
  • src/index.tsx
  • src/schemas.tsx
  • src/types/APIClient.ts
  • test-runner/src/test/kotlin/com/mattermost/networkclient/SessionAttributesTest.kt

Comment thread ios/SessionAttributes/SessionAttributesCollector.swift
Comment thread ios/SessionAttributes/SessionAttributesEngine.swift
Comment thread ios/SessionAttributes/SessionAttributesEngine.swift
Comment thread ios/SessionAttributes/SessionAttributesStore.swift
Comment thread ios/SessionAttributes/SessionAttributesStore.swift
Comment thread src/APIClient/NativeApiClient.ts
@devinbinnie

Copy link
Copy Markdown
Member Author

@coderabbitai resolve all and approve. this has been reviewed already.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

@devinbinnie Resolved CodeRabbit review comments. Approved this pull request.

✅ Action performed

Comments resolved and changes approved.

@devinbinnie
devinbinnie merged commit 0e581bd into master Aug 11, 2026
5 checks passed
@devinbinnie
devinbinnie deleted the MM-69203 branch August 11, 2026 12:44
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.

3 participants