More Security Hardening

This commit is contained in:
Alan Moon 2026-07-23 15:21:37 -07:00
parent 7c51dc217b
commit 0313e52c86
5 changed files with 44 additions and 10 deletions

View File

@ -134,7 +134,6 @@ namespace qtc_api.Controllers
}
[HttpPost("request-password-reset")]
[Authorize]
public async Task<ActionResult<ServiceResponse<bool>>> SendPasswordResetEmail(string email)
{
var user = await _userService.GetUserByEmail(email);

View File

@ -28,7 +28,7 @@ builder.Services.AddControllers();
builder.Services.AddDbContext<DataContext>();
builder.Services.AddSignalR().AddHubOptions<ChatHub>(options =>
{
options.EnableDetailedErrors = true;
options.EnableDetailedErrors = false;
});
builder.Services.AddStackExchangeRedisCache(options =>
@ -43,8 +43,6 @@ builder.Services.AddStackExchangeRedisCache(options =>
options.InstanceName = "QtCNetServer_";
});
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddTransient<IEmailService, EmailService>();
builder.Services.AddScoped<IUserService, UserService>();
@ -55,6 +53,28 @@ builder.Services.AddScoped<StoreService>();
builder.Services.AddScoped<IBucketService, BucketService>();
builder.Services.AddScoped(provider => GetServerConfig());
builder.Services.AddAuthentication().AddJwtBearer(options =>
{
var jwtIssuer = builder.Configuration["Jwt:Issuer"];
var jwtAudience = builder.Configuration["Jwt:Audience"];
var jwtKey = builder.Configuration["Jwt:Key"] ?? Environment.GetEnvironmentVariable("JWT_KEY");
// check configuration for invalid jwt settings
if (jwtIssuer is null || jwtAudience is null || jwtKey is null)
throw new Exception("JWT Validation Parameters Are Not Set In appsettings.json. Please Set These Parameters.");
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtIssuer,
ValidAudience = jwtAudience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey))
};
});
ServerConfig GetServerConfig()
{
if (!File.Exists("./Resources/ServerConfig.json"))

View File

@ -5,7 +5,7 @@
"Price": 100,
"Name": "Example",
"Description": "Change Me!",
"AssetUrl": "https://assets.alanmoon.net/qtc/cosmetics/test/test.gif",
"ThumbnailUrl": "https://assets.alanmoon.net/qtc/cosmetics/test/thumbnail.jpg"
"AssetUrl": "https://cdn.qtchat.net/qtc/cosmetics/test/test.gif",
"ThumbnailUrl": "https://cdn.qtchat.net/qtc/cosmetics/test/thumbnail.jpg"
}
]

View File

@ -13,7 +13,7 @@ namespace qtc_api.Services.BucketService
public string CDNBucketName { get; private set; } = string.Empty;
public string ImagesBucketName { get; private set; } = string.Empty;
private static AmazonS3Client S3Client = new();
private static AmazonS3Client? S3Client;
private IConfiguration _config;
private ILogger<BucketService> _logger;

View File

@ -70,6 +70,13 @@ namespace qtc_api.Services.TokenService
_dataContext.ValidRefreshTokens.Add(refToken);
var existingToken = _dataContext.ValidRefreshTokens.FirstOrDefault(e => e.UserID == refToken.UserID);
if (existingToken != null)
{
refToken.Expires = existingToken.Expires;
_dataContext.ValidRefreshTokens.Remove(existingToken); // we don't want multiple refresh tokens assigned to the user
}
await _dataContext.SaveChangesAsync();
serviceResponse.Message = refToken.Token;
@ -260,15 +267,23 @@ namespace qtc_api.Services.TokenService
{
var serviceResponse = new ServiceResponse<TokenValidationParameters>();
var jwtIssuer = _configuration["Jwt:Issuer"];
var jwtAudience = _configuration["Jwt:Audience"];
var jwtKey = _configuration["Jwt:Key"] ?? Environment.GetEnvironmentVariable("JWT_KEY");
// check configuration for invalid jwt settings
if (jwtIssuer is null || jwtAudience is null || jwtKey is null)
throw new Exception("JWT Validation Parameters Are Not Set In appsettings.json. Please Set These Parameters.");
serviceResponse.Data = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = _configuration["Jwt:Issuer"],
ValidAudience = _configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]!))
ValidIssuer = jwtIssuer,
ValidAudience = jwtAudience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey))
};
return serviceResponse;