Conversation
…orresponding tests Signed-off-by: Grant Ramsay <seapagan@gmail.com>
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferences |
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
…cations Signed-off-by: Grant Ramsay <seapagan@gmail.com>
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
Implements industry-standard password reset UX while maintaining full API compatibility: - Add GET /reset-password/ endpoint to validate token and display HTML form - Enhance POST /reset-password/ to handle both JSON (API) and form data (HTML) - Create password_reset_form.html template with embedded token validation - Create password_reset_success.html template for completion confirmation - Fix GET/POST routing conflict by manually parsing request based on Content-Type - Add proper type annotations for mypy strict mode compliance The existing POST endpoint remains fully functional for frontend SPAs and mobile apps using JSON, while email links now work correctly for users without a frontend.
Add comprehensive documentation for both GET and POST /reset-password/ endpoints: - Document GET endpoint for HTML form display with token validation - Update POST endpoint to clarify it accepts both JSON and form data - Add details about HTML vs JSON responses - Include error messages and usage notes for both endpoints
Introduces flexible password reset flow that works both standalone and with custom frontends: - Add FRONTEND_URL setting to configuration (optional, defaults to None) - Update GET /reset-password/ to redirect to frontend when FRONTEND_URL is set - Fallback to built-in HTML form when FRONTEND_URL is not configured - Add comprehensive documentation for configuration and usage - Update .env.example with FRONTEND_URL setting Benefits: - Standalone: Works out-of-the-box without configuration - Flexible: Seamlessly integrates with React/Vue/Angular frontends - No breaking changes: Existing functionality fully preserved - Solves design clash issue between backend forms and custom frontends
URL-encode the reset token before embedding it in the redirect URL to prevent potential URL manipulation attacks. Security Issue: - The code parameter from user input was directly interpolated into redirect URLs - Special characters (&, ?, #, newlines, etc.) could alter URL structure - Flagged by GitHub CodeQL security scanner Fix: - Import urllib.parse.quote for URL encoding - Encode code parameter before embedding in redirect URL - Ensures special characters are safely percent-encoded - No functional changes, only security hardening All tests pass, no breaking changes.
592565a to
410f85f
Compare
08991ce to
8e81a8f
Compare
Significantly improves test coverage for password reset functionality: Integration Tests (9 new tests): - GET /reset-password/ with valid, invalid, expired tokens - GET /reset-password/ with FRONTEND_URL redirect - POST /reset-password/ with form data (success, validation errors) - POST /reset-password/ form data with invalid tokens - Test coverage improved from 59% to 92% for auth.py Unit Tests (5 new tests): - URL encoding with special characters - URL encoding with normal JWT tokens - URL injection prevention - Frontend URL construction validation - Malicious token encoding safety Coverage Improvement: - app/resources/auth.py: 59% → 92% (37 missed → 7 missed) - Comprehensive testing of all GET and POST form handling paths - FRONTEND_URL redirect behavior fully tested All tests pass with clean linting and type checking.
d337283 to
90ec5ce
Compare
Implements additional security layer for FRONTEND_URL redirects by validating token format and size before redirecting. Security Improvements: - Validate token is not empty before redirect - Reject tokens exceeding 1024 characters (JWT tokens typically 100-500 chars) - Fall back to server-side form display if validation fails - Prevents potential resource exhaustion from huge tokens - Defense against malformed input in redirect flows Changes: - Add max_token_length validation check before redirect in GET endpoint - Empty or oversized tokens skip redirect and show error in built-in form - Add 2 new integration tests for validation behavior All tests pass (29 total), coverage remains at 95% for auth.py. Addresses GitHub CodeQL recommendation for additional input validation in URL redirect flows.
90ec5ce to
02afa2a
Compare
Comprehensive documentation updates and TODO cleanup: API Reference (docs/reference/api.md): - Add "Token Validation" section documenting 1024 character limit - Add "Security Features" section covering: - URL encoding for injection prevention - Length validation for resource exhaustion protection - Redirect safety with FRONTEND_URL - JWT verification and expiration details README.md: - Expand password recovery feature description - Document built-in HTML forms for standalone use - Mention FRONTEND_URL configuration for custom frontends - Note dual support for JSON API and form-based submissions - Highlight security features (URL encoding, token validation) TODO.md: - Remove completed password recovery endpoint task These updates reflect the completed password recovery implementation with security features, comprehensive testing, and documentation.
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
This commit introduces a reusable helper function to validate JWT token format before processing or redirecting with tokens. This provides an additional validation layer that complements cryptographic verification. Changes: - Create app/managers/helpers.py with is_valid_jwt_format() function - Validates 3-part dot-separated structure - Checks base64url character set (A-Z a-z 0-9 - _) - Fast syntactic check without expensive cryptographic operations - Update auth.py reset_password_form() to use helper before redirect - Prevents malformed tokens from being included in redirect URLs - Complements existing length validation (1024 char max) - Add comprehensive unit tests for is_valid_jwt_format() - 8 test methods covering valid/invalid formats - Tests URL injection attempts and edge cases - Validates real-world JWT examples from jwt.io - Add integration test for malformed JWT rejection in redirect flow - Verifies form display instead of redirect for invalid formats Security benefits: - Defense-in-depth: Multiple validation layers before token processing - Better error messages for obviously malformed tokens - Performance: Early rejection of invalid formats - Attack surface reduction: Prevents malformed input in redirect URLs All tests pass (33 integration + 8 unit tests), mypy and ruff checks pass, coverage on auth.py at 95%, helpers.py at 100%.
Signed-off-by: Grant Ramsay <seapagan@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces a secure, token-based password recovery system to the authentication module. It enables users to request a password reset via email, supports both API and HTML form flows, and allows integration with custom frontends via a configurable URL. The update also protects against email enumeration attacks and includes robust validation for token handling.
Password Recovery System:
/forgot-password/) and password resets (/reset-password/), supporting both JSON API and HTML form submissions. Includes secure token generation, validation, and error handling.password_reset.html) for sending password reset links to users.FRONTEND_URLto allow redirecting password reset flows to a custom frontend, with fallback to built-in forms if unset.Security & Validation Enhancements:
is_valid_jwt_formatfor fast syntactic JWT validation before decoding, improving error handling and security.Documentation & Cleanup:
README.mdto document the new password recovery system and its security features.TODO.md.