-
Notifications
You must be signed in to change notification settings - Fork 0
some changes #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
some changes #24
Conversation
There was a problem hiding this 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 introduces email functionality to the OcStockAPI, adding password reset and welcome email capabilities. It also simplifies the application by removing the SuperKey authentication middleware, making database configuration stricter (PostgreSQL only), and enhancing the test controller with additional database inspection endpoints.
- Email Service: New
IEmailServiceinterface andEmailServiceimplementation for sending password reset and welcome emails with HTML templates - Configuration Updates: Added EmailService configuration section with SMTP settings and detailed setup documentation
- Authentication Simplification: Removed SuperKey authentication middleware, made JWT optional in development mode
- Database Enforcement: Removed in-memory database fallback, now requires PostgreSQL connection with automatic migrations
- Development Improvements: Enhanced TestController with database table inspection and summary endpoints (DEBUG-only)
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 20 comments.
Show a summary per file
| File | Description |
|---|---|
| OcStockAPI/Services/Email/IEmailService.cs | New interface defining email service contract with methods for password reset, welcome, and generic emails |
| OcStockAPI/Services/Email/EmailService.cs | Complete email service implementation with SMTP client, HTML email templates, and configuration validation |
| OcStockAPI/appsettings.json | Added EmailService configuration section with SMTP settings and comprehensive documentation for Gmail/SendGrid |
| OcStockAPI/Services/Auth/AuthService.cs | Integrated email service to send welcome emails on registration and password reset emails with token logging fallback |
| OcStockAPI/Program.cs | Major refactoring: removed in-memory DB support, made PostgreSQL mandatory, added auto-migrations, simplified JWT/auth configuration for dev mode |
| OcStockAPI/Controllers/TrackedStocksController.cs | Changed to allow anonymous access in DEBUG builds for easier development testing |
| OcStockAPI/Controllers/TestController.cs | Enhanced with new database inspection endpoints, removed SuperKey test endpoint, wrapped entire controller in DEBUG conditional compilation |
| OcStockAPI/Middleware/SuperKeyAuthenticationMiddleware.cs | Removed entire SuperKey authentication system (100 lines deleted) |
| OcStockAPI/OcStockAPI.csproj | Removed empty wwwroot folder reference |
| OcStockAPI/DataContext/OcStockDbContextFactory.cs | Removed unused imports (Microsoft.EntityFrameworkCore, Microsoft.Extensions.Configuration) |
| OcStockAPI/DataContext/DpapiDbContext.cs | Removed unused imports (Microsoft.EntityFrameworkCore, Microsoft.AspNetCore.Identity, OcStockAPI.Entities.Identity) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| private static string MaskConnectionString(string connectionString) | ||
| { | ||
| if (string.IsNullOrEmpty(connectionString)) | ||
| return "Not configured"; | ||
|
|
||
| return System.Text.RegularExpressions.Regex.Replace( | ||
| connectionString, | ||
| @"Password=[^;]+", | ||
| "Password=***" | ||
| ); | ||
| } |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The MaskConnectionString helper method is duplicated in two places: in Program.cs (lines 69-76) and in TestController.cs (lines 545-555). This code duplication violates DRY principles and makes maintenance harder. Consider extracting this to a shared utility class or helper method that both can use.
| var portString = Environment.GetEnvironmentVariable("EmailService__SmtpPort") | ||
| ?? configuration["EmailService:SmtpPort"]; | ||
| _smtpPort = int.TryParse(portString, out var port) ? port : 587; | ||
|
|
||
| _smtpUsername = Environment.GetEnvironmentVariable("EmailService__SmtpUsername") | ||
| ?? configuration["EmailService:SmtpUsername"]; | ||
|
|
||
| _smtpPassword = Environment.GetEnvironmentVariable("EmailService__SmtpPassword") | ||
| ?? configuration["EmailService:SmtpPassword"]; | ||
|
|
||
| _fromEmail = Environment.GetEnvironmentVariable("EmailService__FromEmail") | ||
| ?? configuration["EmailService:FromEmail"]; | ||
|
|
||
| _fromName = Environment.GetEnvironmentVariable("EmailService__FromName") | ||
| ?? configuration["EmailService:FromName"] | ||
| ?? "OcStock API"; | ||
|
|
||
| // Check if email service is properly configured | ||
| _isConfigured = !string.IsNullOrEmpty(_smtpServer) | ||
| && !string.IsNullOrEmpty(_smtpUsername) | ||
| && !string.IsNullOrEmpty(_smtpPassword) | ||
| && !string.IsNullOrEmpty(_fromEmail); |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The email service configuration validation checks for required fields (lines 45-48) but doesn't validate the _smtpPort value. If the port configuration is invalid or missing, it silently defaults to 587. This could mask configuration errors. Consider adding validation to ensure the port is within valid range (1-65535) and logging a warning if it falls back to the default.
| </div> | ||
| <div class='footer'> | ||
| <p>This is an automated email from OcStock API</p> | ||
| <p>© 2024 OcStock API. All rights reserved.</p> |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The copyright symbol © appears corrupted in the email template. This will display incorrectly in emails sent to users. Consider using the HTML entity © instead for proper rendering across all email clients.
| <p>� 2024 OcStock API. All rights reserved.</p> | |
| <p>© 2024 OcStock API. All rights reserved.</p> |
| var subject = "Welcome to OcStock API! ??"; | ||
|
|
||
| var htmlBody = $@" | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <head> | ||
| <style> | ||
| body {{ font-family: Arial, sans-serif; line-height: 1.6; color: #333; }} | ||
| .container {{ max-width: 600px; margin: 0 auto; padding: 20px; }} | ||
| .header {{ background-color: #4CAF50; color: white; padding: 20px; text-align: center; }} | ||
| .content {{ padding: 20px; background-color: #f9f9f9; }} | ||
| .feature {{ padding: 10px; margin: 10px 0; background-color: white; border-radius: 4px; }} | ||
| .footer {{ padding: 20px; text-align: center; color: #666; font-size: 12px; }} | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <div class='container'> | ||
| <div class='header'> | ||
| <h1>?? Welcome to OcStock API!</h1> | ||
| </div> | ||
| <div class='content'> | ||
| <p>Hello {userName},</p> | ||
| <p>Thank you for registering with OcStock API! Your account has been successfully created.</p> | ||
| <h3>What you can do:</h3> | ||
| <div class='feature'>?? <strong>Track Stocks:</strong> Monitor up to 20 stocks simultaneously</div> | ||
| <div class='feature'>?? <strong>Market News:</strong> Get latest news for your tracked stocks</div> | ||
| <div class='feature'>?? <strong>Economic Data:</strong> Access CPI, unemployment, and interest rates</div> | ||
| <div class='feature'>?? <strong>Stock History:</strong> View historical performance data</div> | ||
| <p>Start exploring by logging into your account and adding stocks to track!</p> | ||
| </div> | ||
| <div class='footer'> | ||
| <p>This is an automated email from OcStock API</p> | ||
| <p>© 2024 OcStock API. All rights reserved.</p> |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple emoji characters in the welcome email template appear corrupted (shown as ??). These include the party popper emoji on line 158, the welcome hand emoji on line 176, and feature icons on lines 183-186. Additionally, the copyright symbol on line 192 is corrupted. These encoding issues will cause the email to display incorrectly. Use HTML entities or descriptive text instead.
|
|
||
| public class EmailService : IEmailService | ||
| { | ||
| private readonly IConfiguration _configuration; |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _configuration field is injected and stored but never used in the class. Consider removing it to reduce unnecessary dependencies, or if it's intended for future use, add a comment explaining its purpose.
| Start exploring by logging into your account and adding stocks to track! | ||
| This is an automated email from OcStock API | ||
| © 2024 OcStock API. All rights reserved. |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The copyright symbol © in the plain text welcome email template appears corrupted. Use (c) or ensure proper character encoding.
| � 2024 OcStock API. All rights reserved. | |
| (c) 2024 OcStock API. All rights reserved. |
| Console.WriteLine("?? To set via user secrets:"); | ||
| Console.WriteLine(" dotnet user-secrets set \"ConnectionStrings:DefaultConnection\" \"your-connection-string\""); | ||
| Console.WriteLine(); | ||
| throw new InvalidOperationException("Database connection string is not configured. Application cannot start without PostgreSQL connection."); |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generic catch clause.
| throw new InvalidOperationException("Database connection string is not configured. Application cannot start without PostgreSQL connection."); | |
| throw new InvalidOperationException("Database connection string is not configured. Application cannot start without PostgreSQL connection.", ex); |
| catch (Exception emailEx) | ||
| { | ||
| _logger.LogWarning(emailEx, "Failed to send welcome email to {Email}", user.Email); | ||
| } |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generic catch clause.
| catch (Exception emailEx) | ||
| { | ||
| _logger.LogError(emailEx, "Error sending password reset email to {Email}", forgotPasswordDto.Email); | ||
| // Log token as fallback | ||
| _logger.LogInformation("Password reset token for {Email}: {Token}", forgotPasswordDto.Email, token); | ||
| } |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generic catch clause.
| catch (Exception ex) | ||
| { | ||
| _logger.LogError(ex, "Error sending email to {ToEmail}", toEmail); | ||
| return false; | ||
| } |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generic catch clause.
| catch (Exception ex) | |
| { | |
| _logger.LogError(ex, "Error sending email to {ToEmail}", toEmail); | |
| return false; | |
| } | |
| catch (FormatException ex) | |
| { | |
| _logger.LogError(ex, "Invalid email address format for {ToEmail}: {Error}", toEmail, ex.Message); | |
| return false; | |
| } | |
| catch (ArgumentException ex) | |
| { | |
| _logger.LogError(ex, "Argument error sending email to {ToEmail}: {Error}", toEmail, ex.Message); | |
| return false; | |
| } |
No description provided.