diff --git a/CHANGELOG.md b/CHANGELOG.md
index ccda336..f7469e6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
+## [7.0.0] - 2023-02-27
+### Added
+ - CORS settings
+
+### Changed
+ - Updated .NET version to 7
+ - Using Serilog.AspNetCore for logging instead of serilog extensions as recommended by Serilog
+ - Log files are now separated by date
+ - Using new syntax for Argument null checks
+ - Updated dependencies
+
## [6.1.0] - 2022-08-15
### Added
- Added dependency Injection
diff --git a/README.md b/README.md
index 3d611ce..bc96236 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,8 @@ This API boilerplate includes the following:
- In Base class in Operations, uncomment the line that establishes db connection
- Update the login controller & user lib.
- This project has a default editorconfig file. If needed customize it.
+ - In program.cs
+ 1. Update CORS websites list
###### Remove the following
- Values controller & values lib
diff --git a/src/WebApiBolierplate/API/API.csproj b/src/WebApiBolierplate/API/API.csproj
index 88dd21d..e995065 100644
--- a/src/WebApiBolierplate/API/API.csproj
+++ b/src/WebApiBolierplate/API/API.csproj
@@ -13,8 +13,8 @@
-
-
+
+
diff --git a/src/WebApiBolierplate/API/Helpers/JWTHelper.cs b/src/WebApiBolierplate/API/Helpers/JWTHelper.cs
index 9c1eb67..17386a2 100644
--- a/src/WebApiBolierplate/API/Helpers/JWTHelper.cs
+++ b/src/WebApiBolierplate/API/Helpers/JWTHelper.cs
@@ -34,10 +34,7 @@ public JWTHelper(IConfiguration configuration)
/// /// User Id is a must
public string GenerateToken(string userId, string userRole = null, string userName = null, string companyId = null)
{
- if (string.IsNullOrEmpty(userId))
- {
- throw new ArgumentNullException("userId", Errors.UserIdMandatory);
- }
+ ArgumentException.ThrowIfNullOrEmpty(userId);
var token = new JwtTokenBuilder()
.AddSecurityKey(_securityKey)
diff --git a/src/WebApiBolierplate/API/Helpers/JwtTokenBuilder.cs b/src/WebApiBolierplate/API/Helpers/JwtTokenBuilder.cs
index 547cb80..93cd46a 100644
--- a/src/WebApiBolierplate/API/Helpers/JwtTokenBuilder.cs
+++ b/src/WebApiBolierplate/API/Helpers/JwtTokenBuilder.cs
@@ -42,10 +42,7 @@ public JwtSecurityToken Build()
///
private void EnsureArguments()
{
- if (securityKey == null)
- {
- throw new ArgumentNullException("Security Key");
- }
+ ArgumentNullException.ThrowIfNull(securityKey);
if (expiryInDays == 0)
{
diff --git a/src/WebApiBolierplate/API/Program.cs b/src/WebApiBolierplate/API/Program.cs
index edf3a4f..e832279 100644
--- a/src/WebApiBolierplate/API/Program.cs
+++ b/src/WebApiBolierplate/API/Program.cs
@@ -6,10 +6,20 @@
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Text;
+using Serilog;
+using Serilog.Events;
var builder = WebApplication.CreateBuilder(args);
-builder.Logging.AddFile("Logs/API.log");
+// If needed, Clear default providers
+builder.Logging.ClearProviders();
+
+// Use Serilog
+builder.Host.UseSerilog((hostContext, services, loggerConfig) => {
+ loggerConfig
+ .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
+ .WriteTo.File( "Logs/api-.log", rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true);
+});
// To prevent .NET and server info from being added to header if Kestrel is used
builder.WebHost.ConfigureKestrel(serverOptions => {
@@ -96,7 +106,6 @@
#endregion Configuring Services
var app = builder.Build();
-
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
@@ -107,7 +116,17 @@
app.UseHsts();
}
+app.UseCors(options =>
+ options
+ .AllowAnyHeader()
+ .AllowAnyMethod()
+ .WithOrigins(new[] { "https://localhost:7030/" })
+);
+
app.UseHttpsRedirection();
+
+app.UseSerilogRequestLogging();
+
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
diff --git a/src/WebApiBolierplate/API/web.config b/src/WebApiBolierplate/API/web.config
index cceec38..d5df36c 100644
--- a/src/WebApiBolierplate/API/web.config
+++ b/src/WebApiBolierplate/API/web.config
@@ -4,17 +4,28 @@
+ Ref: https://learn.microsoft.com/en-us/iis/configuration/
+-->
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/WebApiBolierplate/Core.Lib/Adapters/DBAdapter.cs b/src/WebApiBolierplate/Core.Lib/Adapters/DBAdapter.cs
index 9bbbacd..a2a6aae 100644
--- a/src/WebApiBolierplate/Core.Lib/Adapters/DBAdapter.cs
+++ b/src/WebApiBolierplate/Core.Lib/Adapters/DBAdapter.cs
@@ -9,9 +9,6 @@ public class DBAdapter
#region [Declarations]
private readonly SqlConnection connection;
- private const string SqlCommandNull = "SQL command cannot be null";
- private const string ConnectionStringNull = "Connection string cannot be empty";
- private const string SPNameNull = "Name of the stored procedure must be specified";
#endregion [Declarations]
@@ -20,12 +17,10 @@ public class DBAdapter
///
/// The database connection string
///
+ ///
public DBAdapter(string connectionString)
{
- if (string.IsNullOrEmpty(connectionString))
- {
- throw new ArgumentNullException(connectionString, ConnectionStringNull);
- }
+ ArgumentException.ThrowIfNullOrEmpty(connectionString);
connection = new SqlConnection(connectionString);
connection.Open();
@@ -58,12 +53,10 @@ public DBAdapter(string connectionString)
/// Name of the stored procedure
///
///
+ ///
public SqlCommand GetStoredProcedure(string name)
{
- if (string.IsNullOrEmpty(name))
- {
- throw new ArgumentNullException(name, SPNameNull);
- }
+ ArgumentException.ThrowIfNullOrEmpty(name);
if (connection.State != ConnectionState.Open)
{
connection.Open();
@@ -84,10 +77,7 @@ public SqlCommand GetStoredProcedure(string name)
///
public object ExecuteScalar(SqlCommand dbCommand)
{
- if (dbCommand == null)
- {
- throw new ArgumentNullException("dbCommand", SqlCommandNull);
- }
+ ArgumentNullException.ThrowIfNull(dbCommand);
var result = dbCommand.ExecuteScalar();
return result;
@@ -101,10 +91,7 @@ public object ExecuteScalar(SqlCommand dbCommand)
///
public IDataReader ExecuteReader(SqlCommand dbCommand)
{
- if (dbCommand == null)
- {
- throw new ArgumentNullException("dbCommand", SqlCommandNull);
- }
+ ArgumentNullException.ThrowIfNull(dbCommand);
var result = dbCommand.ExecuteReader();
return result;
@@ -118,10 +105,7 @@ public IDataReader ExecuteReader(SqlCommand dbCommand)
///
public int ExecuteNonQuery(SqlCommand dbCommand)
{
- if (dbCommand == null)
- {
- throw new ArgumentNullException("dbCommand", SqlCommandNull);
- }
+ ArgumentNullException.ThrowIfNull(dbCommand);
var result = dbCommand.ExecuteNonQuery();
return result;
diff --git a/src/WebApiBolierplate/Core.Lib/Security/EncryptionHelper.cs b/src/WebApiBolierplate/Core.Lib/Security/EncryptionHelper.cs
index 69b2a74..54dd6c3 100644
--- a/src/WebApiBolierplate/Core.Lib/Security/EncryptionHelper.cs
+++ b/src/WebApiBolierplate/Core.Lib/Security/EncryptionHelper.cs
@@ -19,7 +19,11 @@ public EncryptionHelper()
private Aes BuildAesEncryptor(string encryptionKey)
{
var aesEncryptor = Aes.Create();
- var pdb = new Rfc2898DeriveBytes(encryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
+ var pdb = new Rfc2898DeriveBytes(
+ password: encryptionKey,
+ salt: "335f0298-9eae-4285-890e-ef7243c974f0"u8.ToArray(),
+ iterations: 5033,
+ hashAlgorithm: HashAlgorithmName.SHA512);
aesEncryptor.Key = pdb.GetBytes(32);
aesEncryptor.IV = pdb.GetBytes(16);
return aesEncryptor;
diff --git a/src/WebApiBolierplate/Core.Lib/Security/HashHelper.cs b/src/WebApiBolierplate/Core.Lib/Security/HashHelper.cs
index 3c5d64b..fdd9b51 100644
--- a/src/WebApiBolierplate/Core.Lib/Security/HashHelper.cs
+++ b/src/WebApiBolierplate/Core.Lib/Security/HashHelper.cs
@@ -17,12 +17,10 @@ public HashHelper()
///
///
///
+ ///
public string HashBCrypt(string plainText)
{
- if (string.IsNullOrEmpty(plainText))
- {
- throw new ArgumentNullException("plainText", AllPrametersMandatory);
- }
+ ArgumentException.ThrowIfNullOrEmpty(plainText);
var hash = BCrypt.Net.BCrypt.HashPassword(plainText, workFactor: 10);
return hash;
@@ -35,12 +33,11 @@ public string HashBCrypt(string plainText)
///
///
///
+ ///
public bool VerifyBCrypt(string plainText, string hash)
{
- if (string.IsNullOrEmpty(plainText) || string.IsNullOrEmpty(hash))
- {
- throw new ArgumentNullException("plainText", AllPrametersMandatory);
- }
+ ArgumentException.ThrowIfNullOrEmpty(plainText);
+ ArgumentException.ThrowIfNullOrEmpty(hash);
var isMatch = BCrypt.Net.BCrypt.Verify(plainText, hash);
return isMatch;