Compare commits

...

10 Commits

Author SHA1 Message Date
rajukottedi 4ab4c615e9 Merge pull request 'dev' (#6) from dev into prod
Reviewed-on: #6
2026-02-16 11:21:06 +05:30
rajukottedi 90d04d7a42 Merge pull request 'Improve URL config parsing and mail exception handling' (#5) from feature/portfolio-admin-auth into dev
Reviewed-on: #5
2026-02-16 11:19:29 +05:30
rajukottedi 2d603e4fc6 Improve URL config parsing and mail exception handling
Refactor Program.cs to robustly parse and validate URLs from config, logging a warning if none are valid. Enhance MailService exception handling to log full exceptions and avoid interrupting OTP generation by swallowing mail send errors.
2026-02-16 11:18:46 +05:30
rajukottedi ec62f5a566 Merge pull request 'dev' (#4) from dev into prod
Reviewed-on: #4
2026-02-16 10:28:59 +05:30
rajukottedi a23953fe11 Merge pull request 'Support encrypted cache conn strings & update dependencies' (#3) from feature/portfolio-admin-auth into dev
Reviewed-on: #3
2026-02-15 14:23:56 +05:30
rajukottedi 2533b5298f Support encrypted cache conn strings & update dependencies
Moved DecryptConnectionString to KBR.Shared.Extensions for reuse and improved configuration access. Added Encryption property to CacheOptions and appsettings for conditional decryption of cache connection strings. Updated ServiceCollectionExtensions to decrypt SQL Server cache connection strings when needed. Upgraded NuGet packages across projects to latest .NET 8/10.0.x versions. Included minor code cleanups and OpenApiSecurityScheme improvements.
2026-02-15 14:22:22 +05:30
rajukottedi b4a9d797dd Merge pull request 'update post details for blog' (#1) from dev into prod
Reviewed-on: #1
2025-01-06 00:01:01 +05:30
rajukottedi eba39f8c5a Merge branch 'dev' of rajukottedi/PortBlog.API into prod 2024-05-09 13:38:03 +05:30
rajukottedi 3a217bc28e Merge branch 'dev' of rajukottedi/PortBlog.API into prod 2024-05-08 22:55:43 +05:30
rajukottedi 0df3605c40 Merge branch 'dev' of rajukottedi/PortBlog.API into prod 2024-05-08 02:08:42 +05:30
10 changed files with 61 additions and 34 deletions
+3 -3
View File
@@ -10,10 +10,10 @@
<ItemGroup>
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.1" />
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
<PackageReference Include="AutoMapper" Version="15.0.1" />
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.1" />
<PackageReference Include="AutoMapper" Version="16.0.0" />
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="9.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.9">
+19 -8
View File
@@ -12,7 +12,7 @@ using PortBlog.API.Middleware;
using Serilog;
using System.Reflection;
using System.Text;
using KBR.Shared.Extensions;
var builder = WebApplication.CreateBuilder(args);
@@ -33,13 +33,25 @@ Log.Logger = loggerConfiguration
.WriteTo.File("logs/portblog.txt", rollingInterval: RollingInterval.Day)
.CreateLogger();
var urls = builder.Configuration.GetSection("Urls");
var urlsSection = builder.Configuration.GetSection("Urls");
var urlsValue = urlsSection.Value;
if (!string.IsNullOrEmpty(urls.Value))
if (!string.IsNullOrWhiteSpace(urlsValue))
{
var allowedUrlsToUse = urls.Value.Split(',');
var allowedUrlsToUse = urlsValue
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
.Where(u => Uri.IsWellFormedUriString(u, UriKind.Absolute))
.ToArray();
builder.WebHost.UseUrls(allowedUrlsToUse);
if (allowedUrlsToUse.Length > 0)
{
builder.WebHost.UseUrls(allowedUrlsToUse);
}
else
{
// optionally log or throw depending on desired behavior
Log.Warning("Configured 'Urls' section was present but no valid URLs were found.");
}
}
var allowedCorsOrigins = builder.Configuration.GetSection("AllowedCorsOrigins");
@@ -131,14 +143,13 @@ builder.Services.AddSwaggerGen(c =>
Scheme = "ApiKeyScheme"
});
var key = new OpenApiSecurityScheme()
var key = new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "ApiKey"
},
In = ParameterLocation.Header
}
};
// JWT Bearer Security Definition
+5 -7
View File
@@ -67,16 +67,14 @@ namespace PortBlog.API.Services
}
catch (Exception ex)
{
logger.LogCritical(
"Exception while sending mail from {FromEmail} ({Name}): {Exception}",
messageSendDto.FromEmail,
messageSendDto.Name,
ex.Message
);
// Log full exception and persist failed message. Do not rethrow to avoid causing a 500 from OTP generation
logger.LogCritical(ex, "Exception while sending mail from {FromEmail} ({Name}).", messageSendDto.FromEmail, messageSendDto.Name);
messageSendDto.SentStatus = (int)MailConstants.MailStatus.Failed;
mailRepository.AddMessage(messageEntity);
await mailRepository.SaveChangesAsync();
throw new Exception();
// swallow the exception so OTP generation continues; caller can inspect delivery status via message logs
return;
}
}
}
@@ -6,6 +6,7 @@
},
"Cache": {
"ConnectionString": "SERVER=192.168.0.197; DATABASE=cv_blog; UID=PortBlogDevUser; PWD=p@$$w0rd1234;Allow User Variables=true;",
"Encryption": "false",
"Provider": "SqlServer"
},
"Jwt": {
+9 -3
View File
@@ -8,10 +8,16 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="coverlet.collector" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
@@ -1,5 +1,6 @@
using KBR.Cache.Constants;
using KBR.Cache.Options;
using KBR.Shared.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -20,9 +21,14 @@ namespace KBR.Cache.Extensions
}
else if (cacheOptions.Provider == CacheProviders.SqlServer)
{
var connectionString = cacheOptions.ConnectionString;
if ((bool)cacheOptions.Encryption)
{
connectionString = configuration.DecryptConnectionString(connectionString);
}
services.AddDistributedMySqlCache(options =>
{
options.ConnectionString = cacheOptions.ConnectionString;
options.ConnectionString = connectionString;
options.TableName = "Cache";
});
}
+8 -8
View File
@@ -7,14 +7,14 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Caching.SqlServer" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.3" />
<PackageReference Include="Pomelo.Extensions.Caching.MySql" Version="2.2.1" />
</ItemGroup>
+2
View File
@@ -4,6 +4,8 @@
{
public string Provider { get; set; } = null!;
public bool? Encryption { get; set; } = false;
public string? ConnectionString { get; set; }
}
}
@@ -1,12 +1,14 @@
using System.Security.Cryptography;
using Microsoft.Extensions.Configuration;
using System.Security.Cryptography;
namespace PortBlog.API.Extensions
namespace KBR.Shared.Extensions
{
public static class ConfigurationExtensions
{
public static string DecryptConnectionString(this IConfiguration configuration, string encryptedConnectionString)
{
string keyBase64 = configuration.GetValue<string>("ConnectionStrings:Key").ToString();
// Fix: Use GetSection and Value instead of GetValue (since GetValue is not available on IConfiguration)
string keyBase64 = configuration.GetSection("ConnectionStrings:Key").Value;
string vectorBase64 = encryptedConnectionString.Split(":")[1];
string cipherText = encryptedConnectionString.Split(":")[0];
+2 -1
View File
@@ -7,7 +7,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="10.0.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.3" />
</ItemGroup>
<ItemGroup>