Initial commit - ECommerce project

This commit is contained in:
2026-08-05 23:58:33 +03:00
commit bcebac18e7
63 changed files with 4543 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
namespace Commerce.Config;
public static class Authentication
{
public static IServiceCollection Authenticate(this IServiceCollection services, ConfigurationManager configuration)
{
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
var jwtKey = configuration["JWT:Key"] ?? throw new InvalidOperationException("JWT:Key is missing in configuration.");
var Key = Encoding.UTF8.GetBytes(jwtKey);
o.SaveToken = true;
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false, // on production make it true
ValidateAudience = false, // on production make it true
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = configuration["JWT:Issuer"],
ValidAudience = configuration["JWT:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Key),
ClockSkew = TimeSpan.Zero
};
o.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Append("IS-TOKEN-EXPIRED", "true");
}
return Task.CompletedTask;
}
};
});
return services;
}
}
+22
View File
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Commerce.Config;
public static class Authorization
{
public static IServiceCollection Authorize(this IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("Admin", policy => policy.RequireRole("ADMIN"));
options.AddPolicy("Moderator", policy => policy.RequireRole("Moderator"));
options.AddPolicy("Seller", policy => policy.RequireRole("Seller"));
});
return services;
}
}
@@ -0,0 +1,55 @@
// using System;
// using System.Collections.Generic;
// using System.Linq;
// using System.Threading.Tasks;
// using Microsoft.AspNetCore.Authorization;
// using Core.Services;
// using System.Security.Claims;
// using Microsoft.AspNetCore.Identity;
// using System.Threading.Tasks;
// namespace Commerce.Config.AuthorizeHandlers;
// public class OrderOwnerOrAdminHandler : AuthorizationHandler<OrderOwnerOrAdminRequirement, Guid>
// {
// // private readonly IServiceProvider _serviceProvider;
// // public OrderOwnerOrAdminHandler(IServiceProvider serviceProvider)
// // {
// // _serviceProvider = serviceProvider;
// // }
// private readonly IServiceProvider _serviceProvider;
// public OrderOwnerOrAdminHandler(IServiceProvider serviceProvider)
// {
// _serviceProvider = serviceProvider;
// }
// protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
// OrderOwnerOrAdminRequirement requirement, Guid orderId)
// {
// using var scope = _serviceProvider.CreateScope();
// var orderService = scope.ServiceProvider.GetRequiredService<OrderService>();
// var user = context.User;
// var userId = user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
// var isAdmin = user.IsInRole("Admin");
// if (isAdmin)
// {
// context.Succeed(requirement);
// return;
// }
// // // var order = await orderService.GetOrderById(orderId.ToString());
// // if (order != null && order.CustomerId == userId)
// // {
// // context.Succeed(requirement);
// // }
// }
// }
// public class OrderOwnerOrAdminRequirement : IAuthorizationRequirement { }
+47
View File
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Commerce.Config;
public static class Cors
{
public static IServiceCollection AddCustomCors(this IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.WithExposedHeaders("X-Pagination"); // This line!
// .AllowCredentials()
// .SetIsOriginAllowedToAllowWildcardSubdomains() // For SameSite=None
// .WithExposedHeaders("*");
});
options.AddPolicy(
"default",
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.WithExposedHeaders("X-Pagination"); // This line!
// .AllowCredentials()
// .SetIsOriginAllowedToAllowWildcardSubdomains() // For SameSite=None
// .WithExposedHeaders("*");
}
);
});
return services;
}
}
+27
View File
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Commerce.Config;
public static class FluentEmailExtensions
{
public static void RegFluentEmail(
this IServiceCollection services,
ConfigurationManager configuration
)
{
var emailSettings = configuration.GetSection("MailSettings");
var defaultFromEmail = emailSettings["Mail"];
var host = emailSettings["Host"];
var port = emailSettings.GetValue<int>("Port");
var userName = emailSettings["UserName"];
var password = emailSettings["Password"];
services
.AddFluentEmail(defaultFromEmail)
.AddSmtpSender(host, port, userName, password)
.AddRazorRenderer();
}
}
+21
View File
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Commerce.Core.Services;
using Microsoft.AspNetCore.Authorization;
namespace Commerce.Config;
public static class RegisteringServices
{
public static IServiceCollection RegisterServices(this IServiceCollection services)
{
//test
services.AddScoped<ProductService>();
services.AddScoped<CategoryService>();
return services;
}
}
+29
View File
@@ -0,0 +1,29 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Scalar.AspNetCore;
namespace Commerce.Config;
public static class Swagger
{
public static IServiceCollection AddSwag(this IServiceCollection services)
{
services.AddOpenApi(options =>
{
options.AddDocumentTransformer((document, context, cancellationToken) =>
{
document.Info.Title = "Commerce API";
document.Info.Version = "v1";
return Task.CompletedTask;
});
});
return services;
}
public static IEndpointRouteBuilder UseSwag(this IEndpointRouteBuilder app)
{
app.MapScalarApiReference();
return app;
}
}