EMERGENCY FIXES: ✅ DELETE MockSilverPayService.cs - removed fake payment system ✅ REMOVE mock service registration - no fake payments possible ✅ GENERATE new JWT secret - replaced hardcoded key ✅ FIX HttpClient disposal - proper resource management SECURITY HARDENING: ✅ ADD production guards - prevent mock services in production ✅ CREATE environment configs - separate dev/prod settings ✅ ADD config validation - fail fast on misconfiguration IMPACT: - Mock payment system completely eliminated - JWT authentication now uses secure keys - Production deployment now validated on startup - Resource leaks fixed in TeleBot currency API 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
159 lines
4.6 KiB
C#
159 lines
4.6 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using System.Text.Json;
|
|
using LittleShop.Data;
|
|
using LittleShop.Models;
|
|
|
|
namespace LittleShop.Services;
|
|
|
|
public class SystemSettingsService : ISystemSettingsService
|
|
{
|
|
private readonly LittleShopContext _context;
|
|
private readonly ILogger<SystemSettingsService> _logger;
|
|
|
|
public SystemSettingsService(LittleShopContext context, ILogger<SystemSettingsService> logger)
|
|
{
|
|
_context = context;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<string?> GetSettingAsync(string key)
|
|
{
|
|
try
|
|
{
|
|
var setting = await _context.SystemSettings
|
|
.FirstOrDefaultAsync(s => s.Key == key);
|
|
return setting?.Value;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error getting setting {Key}", key);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<T?> GetSettingAsync<T>(string key, T? defaultValue = default)
|
|
{
|
|
try
|
|
{
|
|
var setting = await GetSettingAsync(key);
|
|
if (string.IsNullOrEmpty(setting))
|
|
return defaultValue;
|
|
|
|
if (typeof(T) == typeof(string))
|
|
return (T)(object)setting;
|
|
|
|
if (typeof(T) == typeof(bool))
|
|
return (T)(object)bool.Parse(setting);
|
|
|
|
if (typeof(T) == typeof(int))
|
|
return (T)(object)int.Parse(setting);
|
|
|
|
if (typeof(T) == typeof(decimal))
|
|
return (T)(object)decimal.Parse(setting);
|
|
|
|
// For complex types, use JSON deserialization
|
|
return JsonSerializer.Deserialize<T>(setting);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error parsing setting {Key} as {Type}", key, typeof(T).Name);
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
public async Task SetSettingAsync(string key, string value, string? description = null)
|
|
{
|
|
try
|
|
{
|
|
var setting = await _context.SystemSettings
|
|
.FirstOrDefaultAsync(s => s.Key == key);
|
|
|
|
if (setting == null)
|
|
{
|
|
setting = new SystemSetting
|
|
{
|
|
Key = key,
|
|
Value = value,
|
|
Description = description,
|
|
CreatedAt = DateTime.UtcNow,
|
|
UpdatedAt = DateTime.UtcNow
|
|
};
|
|
_context.SystemSettings.Add(setting);
|
|
}
|
|
else
|
|
{
|
|
setting.Value = value;
|
|
setting.UpdatedAt = DateTime.UtcNow;
|
|
if (description != null)
|
|
setting.Description = description;
|
|
}
|
|
|
|
await _context.SaveChangesAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error setting {Key} to {Value}", key, value);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public async Task SetSettingAsync<T>(string key, T value, string? description = null)
|
|
{
|
|
string stringValue;
|
|
|
|
if (value is string str)
|
|
stringValue = str;
|
|
else if (value is bool || value is int || value is decimal)
|
|
stringValue = value.ToString()!;
|
|
else
|
|
stringValue = JsonSerializer.Serialize(value);
|
|
|
|
await SetSettingAsync(key, stringValue, description);
|
|
}
|
|
|
|
public async Task<bool> DeleteSettingAsync(string key)
|
|
{
|
|
try
|
|
{
|
|
var setting = await _context.SystemSettings
|
|
.FirstOrDefaultAsync(s => s.Key == key);
|
|
|
|
if (setting == null)
|
|
return false;
|
|
|
|
_context.SystemSettings.Remove(setting);
|
|
await _context.SaveChangesAsync();
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error deleting setting {Key}", key);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public async Task<Dictionary<string, string>> GetAllSettingsAsync()
|
|
{
|
|
try
|
|
{
|
|
return await _context.SystemSettings
|
|
.ToDictionaryAsync(s => s.Key, s => s.Value);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error getting all settings");
|
|
return new Dictionary<string, string>();
|
|
}
|
|
}
|
|
|
|
public async Task<bool> IsTestCurrencyEnabledAsync(string currency)
|
|
{
|
|
return await GetSettingAsync($"TestCurrency.{currency}.Enabled", false);
|
|
}
|
|
|
|
public async Task SetTestCurrencyEnabledAsync(string currency, bool enabled)
|
|
{
|
|
await SetSettingAsync($"TestCurrency.{currency}.Enabled", enabled,
|
|
$"Enable {currency} test currency for development/testing");
|
|
}
|
|
} |