Add FastAPI web service with Next.js UI#33
Conversation
- Add FastAPI sidecar API with multipart form handling and file processing - Create modular router structure for all SVG operations (create, add, remove, rename, list, extract, inspect, validate, split-paths) - Implement async dependency injection for temporary directory lifecycle management - Add Pydantic response models for consistent API responses - Implement SVG upload sanitization to strip scripts and enforce size limits - Add Next.js web UI with dark mode support and responsive design - Create reusable React components for file upload, processing options, and results display - Add theme context and API client hooks for seamless frontend-backend integration - Update CLI with `web` command to launch the API server and UI - Update project configuration for optional web dependencies and static asset bundling - Update architecture documentation with API design patterns and request lifecycle - Update .gitignore to exclude built web artifacts and Next.js cache - Update CHANGELOG and version metadata for v1.3.0 release
- Update pre-commit config to include pydantic and fastapi type stubs - Replace typing.AsyncGenerator with collections.abc.AsyncGenerator for Python 3.13 compatibility - Prefix unused request parameters with underscore in exception handlers - Add mypy overrides for pydantic, fastapi, and api modules to handle untyped decorators - Add ruff lint exception for FastAPI Depends() pattern in router defaults - Improve import organization and line wrapping for readability - Add type: ignore comments for FastAPI exception handler registrations - Update return type annotations for consistency across routers
- Replace unsafe path concatenation with safe_path_join in all router endpoints - Capture and use sanitized SVG content instead of discarding sanitization result - Add safe_path_join import to extract, inspect, list, remove, rename, and split_paths routers - Add sanitize_svg_upload import to split_paths router - Ensure uploaded files are properly validated before writing to disk - Prevent path traversal vulnerabilities in file upload handling
- Add web extra to pip install command in CI workflow - Ensures web service dependencies are available during CI runs - Allows web-related tests and checks to execute properly
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
- Extract dangerous elements set to use only local tag names - Replace event handler prefix tuple with string constant - Add JavaScript URI attributes set constant for reusable validation - Update attribute filtering logic to use defined constants instead of hardcoded values - Improves code maintainability and reduces duplication in sanitization checks
- Add duplicate filename detection in add_icons and create_library endpoints - Generate unique filenames with counter suffix when duplicates are detected - Improve filename handling for uploads without explicit filenames - Refactor conditional logic in _strip_dangerous_content for better readability - Fix operator precedence in JavaScript URI attribute validation checks - Prevents file overwrites when multiple SVGs with same filename are uploaded
- Remove duplicate SVG upload handling logic from add_icons and create_library endpoints - Extract file deduplication and sanitization into new process_svg_uploads function - Improve SVG root tag validation to handle XML namespaces correctly - Add whitespace stripping to JavaScript URI detection for better security - Remove unused SplitPathsStats model from responses - Consolidate upload processing logic into reusable service function to reduce code duplication
- Add tests for SVG upload sanitization covering valid SVGs, size limits, and XML validation - Add tests for dangerous element removal (script, foreignObject, event handlers) - Add tests for JavaScript URI stripping in href, xlink:href, and src attributes - Add tests for whitespace-prefixed javascript: URIs (Bug #8) - Add tests for safe attribute and href preservation - Add tests for SVG processing options builder with default and custom configurations - Add tests for API routers covering file upload endpoints and error handling - Add tests for CLI web service integration - Add httpx dependency to dev dependencies for HTTP testing - Ensure comprehensive coverage of security sanitization and API functionality
- Convert single quotes to double quotes in SVG test strings - Remove trailing whitespace from blank lines - Add blank line after imports in test_cli_web.py - Remove unused imports (sys, threading) from test_cli_web.py - Reformat long argument lists to multi-line for readability - Consolidate method signatures that exceeded line length limits - Improve code formatting consistency across test suite
- Add --no-warn-unused-ignores flag to mypy args in pre-commit config - Add type ignore comments to httpx client.post calls in test_api_routers.py - Suppress mypy warnings for httpx type variance issues in file upload tests - Improves CI linting consistency and reduces false positive warnings
- Refactor process_svg_uploads to return list of SVG paths instead of requiring glob after call - Update add.py router to use returned paths directly - Update create.py router to use returned paths directly - Simplifies caller logic and reduces redundant file system operations - Add test cases for uppercase .SVG file extension handling (Bug #12) - Update production environment to use relative API URL for same-origin requests
- Add ConflictError exception class for resource conflicts (HTTP 409) - Add conflict_error_handler to convert ConflictError to HTTP 409 responses - Register ConflictError handler in FastAPI exception handlers - Update rename_icon endpoint to catch ValueError and raise ConflictError when icon already exists - Fix web CLI to use localhost for display when binding to 0.0.0.0 - Reorganize test classes in test_api_processing.py for better structure - Add test case for rename conflict returning 409 status code - Improves error handling for duplicate icon names during rename operations
- Register SVG namespace in ElementTree to prevent ns0: prefixes during serialization - Add test case to verify namespace is preserved without unwanted prefixes - Ensures sanitized SVG output maintains proper namespace declaration without namespace prefix pollution
- Remove global ValueError exception handler from main.py to prevent masking internal errors
- Add explicit ValueError handling in add, extract, inspect, list, remove, and rename routers
- Return 422 Unprocessable Entity for library format/parsing errors ("Invalid library")
- Let other ValueErrors propagate as 500 Internal Server Error for true processing failures
- Import HTTPException in routers that need explicit error handling
- Add clarifying comments explaining ValueError handling strategy
- Update test suite to verify correct HTTP status codes for library validation errors
- Change default `add_css` option from false to true in CreateTab - Change default `add_css` option from false to true in ManageTab - Aligns with improved SVG sanitization and processing pipeline to provide styled output by default
- Remove redundant type ignore comment from test_api_routers.py - Comment was suppressing httpx type variance warning that is no longer needed - Improves code clarity by eliminating outdated type suppression
- Remove generic ValueError handler from global exception middleware - ValueError handling now delegated to individual routers for context-specific responses - Aligns with explicit error handling pattern established in recent commits
- Add try-except blocks in add_icons and create_library to catch ValueError - Convert ValueError to HTTPException with 422 status code for invalid parameters - Import HTTPException in create.py router module - Add test cases for invalid css_mode validation in both endpoints - Ensures API returns proper validation error responses instead of unhandled exceptions
- Remove global ImportError exception handler to avoid masking genuine import bugs - Add explicit ImportError handling in split_paths endpoint for missing optional dependencies - Implement _has_dangerous_uri() helper function to detect javascript: and data: URI schemes - Extend SVG sanitization to strip data: URIs from href, xlink:href, and src attributes - Add comprehensive test coverage for data: URI sanitization across different attributes - Update sanitization logic to use centralized dangerous URI detection instead of inline checks - Add clarifying comments about why ImportError is not handled globally
- Import sanitize_filename helper in process_svg_uploads function - Apply filename sanitization before duplicate detection logic - Use sanitized filename for stem/extension extraction in counter loop - Add test case for create endpoint with sanitized duplicate filenames - Add test case for add endpoint with sanitized duplicate filenames - Ensures filenames like "icon<1>.svg" and "icon_1_.svg" are properly deduplicated after sanitization (Bug #22)
…ublish workflow - Add type validation for icon_names parameter in extract, inspect, and remove endpoints to ensure it's a JSON array, not a string, number, or object - Raise HTTPException with 422 status code when icon_names is valid JSON but not an array type - Include actual type name in error message for better debugging (e.g., "got str", "got int", "got dict") - Add comprehensive test coverage for non-list JSON inputs across all three endpoints - Set up Node.js 20 in publish workflow with npm caching - Install web UI dependencies and build web UI as part of release process - Copy built web UI into package before publishing to PyPI - Fixes Bug #23 where non-array JSON values were not properly rejected
- Extract JSON parsing logic for icon_names into reusable parse_icon_names function in processing service - Add validation for sizing strategy warnings in add and create endpoints - Raise HTTPException with 422 status when width/height are mismatched or incomplete - Remove duplicate icon_names parsing code from extract, inspect, and remove routers - Update routers to use centralized parse_icon_names function - Add comprehensive tests for parse_icon_names validation and sizing warnings - Reduces code duplication and improves maintainability of icon name validation
- Add type validation for each element in parsed icon_names JSON array - Reject non-string elements (dicts, numbers, etc.) with 422 status code - Include element type and index in error detail for debugging - Add comprehensive test cases for dict, number, and mixed-type elements - Prevents downstream errors from malformed icon name data
- Replace blanket data: URI block with targeted dangerous type filtering - Allow safe image data URIs (image/png, image/jpeg, image/svg+xml, image/gif) - Block dangerous data URI types (text/html, text/javascript, application/javascript) - Continue blocking all javascript: URIs - Update sanitization logic to check MIME type prefix instead of scheme only - Add comprehensive test coverage for safe image data URIs - Add tests for application/javascript and application/x-javascript blocking - Update existing test assertions to check for specific dangerous types - Improve test case insensitivity handling with normalized string comparison
- Normalize element tag names to lowercase before checking against dangerous elements set - Update _DANGEROUS_ELEMENTS to store "foreignobject" in lowercase for consistent matching - Add case-insensitive matching logic in _strip_dangerous_content function - Add comprehensive test coverage for case-variant script elements (uppercase, mixed case, with namespace) - Add comprehensive test coverage for case-variant foreignObject elements (uppercase, mixed case) - Fixes Bug #28: SVG sanitization now properly removes dangerous elements regardless of case variation
- Extract duplicate ValueError handling logic from 5 router modules into reusable handle_library_value_error function - Remove HTTPException imports from extract, inspect, list, and remove routers as they're no longer needed - Update add, extract, inspect, list, and remove routers to use centralized error handler - Consolidate library format/parsing error detection (422) vs internal error (500) logic in single location - Improve maintainability by eliminating repeated error handling patterns across routers
- Add library format error handling to rename_icon endpoint - Check for "Invalid library" error messages and delegate to handle_library_value_error - Update handle_library_value_error return type to NoReturn for clarity - Add docstring note that function always raises an exception - Add test case for invalid library format returning 422 status code - Ensures consistent error handling across all endpoints that process library files
- Change navbar title from "SVG2DrawIO" to "SVG2DrawIOLib" - Update logo link to point to GitHub repository instead of internal /create route - Align branding with project repository name for consistency
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| "data:text/javascript", | ||
| "data:application/javascript", | ||
| "data:application/x-javascript", | ||
| } |
There was a problem hiding this comment.
SVG data URIs bypass script sanitization
Medium Severity
The _DANGEROUS_DATA_URI_TYPES set does not include data:image/svg+xml, and the comment on line 25 explicitly classifies it as a "safe image type." However, data:image/svg+xml URIs can contain <script> elements, event handlers, and other executable content — the very things sanitize_svg_upload is designed to strip. This creates a bypass: a <image href="data:image/svg+xml,<svg onload='alert(1)'/>"/> would pass sanitization with the embedded script intact.


webcommand to launch the API server and UINote
Medium Risk
Adds a new HTTP surface area (file uploads + static hosting) and changes packaging/release flow to bundle built web assets, which could affect security and distribution integrity if misconfigured.
Overview
Adds an optional browser-based Web UI (
svg2drawio web) backed by a newFastAPIsidecar undersrc/SVG2DrawIOLib/api/, exposing the existing CLI operations via/api/*endpoints and serving a bundled static frontend from the wheel.Introduces upload hardening and API ergonomics: per-request temp-dir lifecycle, SVG sanitization with a 10MB limit, consistent error→HTTP mapping, and file-returning endpoints switched to in-memory
Response(content=...)to avoid Windows temp cleanup races. Packaging/CI/release are updated to include a[web]extra, bundle the built UI into distributions (Node only for publishing/build), add Makefile dev/build targets, and expand tests/docs/version to1.3.0.Written by Cursor Bugbot for commit ea16510. This will update automatically on new commits. Configure here.