cli icon indicating copy to clipboard operation
cli copied to clipboard

feat(graphiql): add shared types, constants, and validation

Open amcaplan opened this issue 3 months ago β€’ 2 comments

WHY are these changes introduced?

This PR builds on the foundation from PR #6578 by establishing the core type system, configuration validation, and default content for the GraphiQL console. This is the second PR in the 8-PR migration stack.

Context: The GraphiQL console will receive configuration from the Rails server via window.__GRAPHIQL_CONFIG__. This configuration includes URLs, API endpoints, and user data. We need:

  • Strong TypeScript types for configuration data
  • Security validation to prevent XSS attacks through config injection
  • Default content for the welcome screen and initial queries

WHAT is this pull request doing?

This PR adds the type definitions, security validation layer, and default content that will be used throughout the GraphiQL application.

Key Changes:

1. Type Definitions (src/types/config.ts):

  • GraphiQLConfig interface defining all configuration fields
  • Server data: apiVersion, apiVersions, appName, appUrl, storeFqdn
  • API endpoints: baseUrl
  • Optional initial state: query, variables, defaultQueries
  • Global window interface extension for window.__GRAPHIQL_CONFIG__

2. Security Validation (src/utils/configValidation.ts):

  • XSS Prevention: Validates all URLs to only allow http/https protocols
  • URL Allowlist: Restricts URLs to localhost and *.myshopify.com domains
  • String Sanitization: Detects and blocks script tags, event handlers, and javascript: URLs
  • Safe Fallbacks: Returns sanitized config with dangerous values replaced by safe defaults
  • Comprehensive 313-line test suite covering all attack vectors

Security Patterns Blocked:

// All of these would be rejected:
javascript:alert('xss')
data:text/html,<script>alert('xss')</script>
http://evil.com/steal-tokens
<script>alert('xss')</script>
<img onerror="alert('xss')" src=x>

3. Default Content (src/constants/defaultContent.ts):

  • Welcome message explaining GraphiQL features and keyboard shortcuts
  • Platform-aware control key display (⌘ for Mac, Ctrl for Windows/Linux)
  • Default shop query to fetch basic store information

Files Added:

  • src/types/config.ts - TypeScript interfaces
  • src/constants/defaultContent.ts - Welcome message and default query
  • src/utils/configValidation.ts - Security validation (153 lines)
  • src/utils/configValidation.test.ts - Security tests (313 lines)

Dependencies

Builds on: PR #6578 (package foundation)

How to test your changes?

# Run the comprehensive security validation tests
pnpm --filter @shopify/graphiql-console test src/utils/configValidation.test.ts

# Type check the new interfaces
pnpm --filter @shopify/graphiql-console tsc --noEmit

# All 313 test cases should pass, covering:
# - URL protocol validation
# - XSS attack prevention
# - Shopify domain allowlist
# - String sanitization
# - Safe fallback behavior

Measuring impact

  • [x] n/a - this is foundational security infrastructure

Checklist

  • [x] I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • [x] I've considered possible documentation changes

amcaplan avatar Nov 06 '25 14:11 amcaplan

[!WARNING] This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite. Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

amcaplan avatar Nov 06 '25 14:11 amcaplan

Coverage report

St.:grey_question:
Category Percentage Covered / Total
🟑 Statements 79.33% 13657/17216
🟑 Branches 73.23% 6687/9132
🟑 Functions 79.42% 3520/4432
🟑 Lines 79.69% 12899/16187

Test suite run success

3385 tests passing in 1385 suites.

Report generated by πŸ§ͺjest coverage report action from 9296984ba76177af0d4945564ef909e89485b0b7

github-actions[bot] avatar Nov 06 '25 14:11 github-actions[bot]