Skip to content

Conversation

@ssestak
Copy link
Collaborator

@ssestak ssestak commented Nov 25, 2025

Summary

Adds GraphQL query string tracking to AnalyticEntry for analyzing query complexity and structure patterns. Implements secure-by-default literal masking to protect against accidental data leakage through inline values.

Changes

Core Implementation

  • AnalyticEntry: Added query property
  • AnalyticsConfiguration: Added maskQueryLiterals (default: true)
  • FTNetworkTracer: Wired query parameter through to analytics
  • Query Masking Algorithm: Masks string/number literals, preserves variable references and structure

Privacy Behavior

Privacy Level Query Included? Masking Applied?
.none Yes Yes (if maskQueryLiterals: true)
.private Yes Yes (if maskQueryLiterals: true)
.sensitive No (nil) N/A

Test Coverage

  • Added 7 comprehensive unit tests in AnalyticsTests
  • Added 1 integration test for end-to-end query flow
  • Edge case testing for special characters in string literals
  • All 75 tests passing

Documentation

  • Updated CLAUDE.md with query masking documentation
  • Documented configuration options and privacy levels

Breaking Changes

None - Purely additive change with backward compatibility

Rationale

  1. Secure by default: Masking enabled prevents accidental data leakage
  2. Consistent: Matches existing maskVariables behavior
  3. Preserves analysis: Query structure retained for complexity tracking
  4. Flexible: Can opt out with maskQueryLiterals: false
  5. Privacy-focused: Aligns with Privacy by Design principle

🤖 Generated with Claude Code

Add GraphQL query string tracking to AnalyticEntry for analyzing query
complexity and structure patterns. Implements secure-by-default literal
masking to protect against accidental data leakage through inline values.

Changes:
- Add `query: String?` property to AnalyticEntry
- Add `maskQueryLiterals: Bool` to AnalyticsConfiguration (default: true)
- Implement query masking algorithm that:
  - Masks string literals ("admin" → "***")
  - Masks number literals (123 → ***)
  - Preserves variable references ($userId)
  - Preserves query structure for complexity analysis
- Wire query parameter through FTNetworkTracer
- Add 7 comprehensive tests for query masking functionality
- Update CLAUDE.md documentation

Privacy Levels:
- .none/.private: Query included with optional literal masking
- .sensitive: Query set to nil (most restrictive)

Breaking Changes: None (purely additive)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@ssestak
Copy link
Collaborator Author

ssestak commented Nov 25, 2025

1 Warning
⚠️ This PR is quite large. Consider breaking it into smaller PRs for easier review.
4 Messages
📖 ⚠️ This PR modifies security-sensitive files: Sources/FTNetworkTracer/Analytics/AnalyticEntry.swift, Sources/FTNetworkTracer/Analytics/AnalyticsConfiguration.swift, Tests/FTNetworkTracerTests/AnalyticsTests.swift, Tests/FTNetworkTracerTests/SecurityTests.swift
📖 Please ensure SecurityTests.swift covers these changes
📖 🎉 Great job adding comprehensive tests!
📖 🔒 Security tests updated - excellent!

Generated by 🚫 Danger

Šimon Šesták and others added 2 commits November 25, 2025 12:23
Refactored maskQueryLiteralValues function to address SwiftLint violations:
- Extracted state into QueryMaskingState struct
- Split complex switch logic into smaller helper methods
- Reduced cyclomatic complexity from 20 to acceptable levels
- Reduced function body length from 80 to under 50 lines
- Fixed conditional returns on newline warning

All tests still passing (75/75).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add comprehensive documentation for the new GraphQL query masking feature:
- Added maskQueryLiterals configuration example
- Updated privacy levels table to include GraphQL query behavior
- Added "What Gets Masked" section for GraphQL query literals
- Added visual example showing query masking in action
- Updated test coverage to reflect 75 total tests
- Added usage example in MyAnalytics class showing query analysis
- Updated features list to highlight GraphQL query masking

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds GraphQL query string tracking to AnalyticEntry with privacy-focused literal masking to prevent accidental data leakage. The implementation provides secure-by-default behavior while allowing flexibility for teams that need unmasked queries.

  • Added query property to AnalyticEntry with automatic privacy masking based on configuration
  • Implemented literal masking algorithm that masks string and number literals while preserving query structure and variable references
  • Added maskQueryLiterals configuration option (default: true) to allow opt-out of masking
  • Comprehensive test coverage with 7 new unit tests and 1 integration test

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Sources/FTNetworkTracer/Analytics/AnalyticEntry.swift Added query property with masking applied via configuration
Sources/FTNetworkTracer/Analytics/AnalyticsConfiguration.swift Added maskQueryLiterals config option and masking algorithm implementation
Sources/FTNetworkTracer/FTNetworkTracer.swift Wired query parameter through to AnalyticEntry
Tests/FTNetworkTracerTests/AnalyticsTests.swift Added 7 comprehensive unit tests for query masking behavior
Tests/FTNetworkTracerTests/IntegrationTests.swift Added end-to-end integration test for query analytics flow
README.md Updated documentation with query masking examples and privacy table
CLAUDE.md Updated developer documentation with query masking details

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Šimon Šesták and others added 2 commits November 25, 2025 13:51
Security Fixes:
- Fix unclosed string literal vulnerability
- Fix parentheses handling inside string literals
- Malformed queries now safely mask content

Test Coverage:
- Add 5 security tests for GraphQL query masking
- Test PII masking, SQL injection, XSS payloads
- Test malformed queries with unclosed strings
- Total: 80 tests passing

Documentation:
- Clarify preserved literal types in README
- Document booleans, nulls, enums are preserved

Addresses Copilot comments and Danger bot request.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Refactors QueryLiteralMasker to take query as init parameter
and expose masked result as a property.

Design improvements:
- Query passed to init, maskedQuery exposed as property
- Internal Processor struct handles state and processing
- Clean separation between public API and implementation
- Fixes SwiftLint type_body_length violation

Technical:
- All 80 tests passing
- SwiftLint: 0 violations
- AnalyticsConfiguration: 184 lines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <[email protected]>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ssestak ssestak merged commit ef0b359 into main Jan 7, 2026
10 checks passed
@ssestak ssestak deleted the feature/add-query-property-to-analytic-entry branch January 7, 2026 14:03
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