Initial commit - ERP
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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
@@ -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
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Executable
+57
@@ -0,0 +1,57 @@
|
|||||||
|
FROM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS base
|
||||||
|
|
||||||
|
# WORKDIR /app
|
||||||
|
# ENV DOTNET_URLS=http://*:2000
|
||||||
|
#ENV ConnectionStrings__PostgreDB="Host=db;Database=ECommerce;Username=said;Password=aaa111!!!AAA;Port=5435;"
|
||||||
|
|
||||||
|
ENV ASPNETCORE_ENVIRONMENT=Production
|
||||||
|
|
||||||
|
FROM base AS build
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
|
||||||
|
RUN dotnet tool install --global dotnet-ef --version 9.0.*
|
||||||
|
ENV PATH="$PATH:/root/.dotnet/tools"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
COPY ./Core/ ./Core
|
||||||
|
COPY ./Contracts/ ./Contracts
|
||||||
|
COPY ./Domain/ ./Domain
|
||||||
|
COPY ./ECommerce_API/ ./ECommerce_API
|
||||||
|
|
||||||
|
RUN dotnet ef migrations script --startup-project ECommerce_API --project Domain -o sqlscript.sql
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WORKDIR /src/ECommerce_API
|
||||||
|
RUN dotnet restore
|
||||||
|
RUN dotnet build -c Release -o /build
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
|
||||||
|
FROM build AS publish
|
||||||
|
|
||||||
|
WORKDIR /src/ECommerce_API
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RUN dotnet publish -c Release -o /app/publish
|
||||||
|
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine3.21-amd64 AS runtime
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=publish /app/publish .
|
||||||
|
COPY --from=build /src/sqlscript.sql .
|
||||||
|
# ENV PATH="$PATH:/root/.dotnet/tools"
|
||||||
|
ENV ASPNETCORE_URLS=http://*:80
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# COPY --from=publish /src/Core.Contracts/EmailTemplates/. ./EmailTemplates
|
||||||
|
ENTRYPOINT ["dotnet", "ECommerce_API.dll"]
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="FluentEmail.Core" Version="3.0.2" />
|
||||||
|
<PackageReference Include="FluentEmail.Razor" Version="3.0.2" />
|
||||||
|
<PackageReference Include="FluentEmail.Smtp" Version="3.0.2" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="9.0.5" />
|
||||||
|
<PackageReference Include="Scalar.AspNetCore" Version="2.12.11" />
|
||||||
|
<!-- <PackageReference Include="Npgsql" Version="8.0.3" /> -->
|
||||||
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.12.0" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.5" />
|
||||||
|
<!-- <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" /> -->
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.5" />
|
||||||
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
||||||
|
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="../ECommerce.Core/ECommerce.Core.csproj" />
|
||||||
|
|
||||||
|
<ProjectReference Include="../ECommerce.Contracts/ECommerce.Contracts.csproj" />
|
||||||
|
<!-- <ProjectReference Include="..\Domain\Domain.csproj" /> -->
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Commerce.Endpoints.v1;
|
||||||
|
|
||||||
|
namespace Commerce.Endpoints;
|
||||||
|
|
||||||
|
public static class RegisterEndpoints
|
||||||
|
{
|
||||||
|
public static void MapAPIv1(this IEndpointRouteBuilder app)
|
||||||
|
{
|
||||||
|
//hello
|
||||||
|
app.MapGroup("api/v1/").ProductEndpoints().WithTags("Product").RequireCors("default");
|
||||||
|
app.MapGroup("api/v1/").CategoryEndpoints().WithTags("Category").RequireCors("default");
|
||||||
|
}
|
||||||
|
public static void MapAPIv2(this IEndpointRouteBuilder app)
|
||||||
|
{
|
||||||
|
//hello
|
||||||
|
app.MapGroup("api/v1/").ProductEndpoints().WithTags("Product").RequireCors("default");
|
||||||
|
app.MapGroup("api/v1/").CategoryEndpoints().WithTags("Category").RequireCors("default");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
|
||||||
|
using Commerce.Contracts.DTOs;
|
||||||
|
using Commerce.Core.Services;
|
||||||
|
using Commerce.Domain.Entities;
|
||||||
|
using Generic.Contracts.Generics;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Commerce.Endpoints.v1;
|
||||||
|
|
||||||
|
public static class CategoryMap
|
||||||
|
{
|
||||||
|
public static RouteGroupBuilder CategoryEndpoints(this RouteGroupBuilder group)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// No Fetch
|
||||||
|
group.MapGet(
|
||||||
|
"categories",
|
||||||
|
async (
|
||||||
|
[AsParameters] CategoryFilter categoryFilter,
|
||||||
|
[AsParameters] Pagination pagination,
|
||||||
|
CategoryService categoryService,
|
||||||
|
HttpContext httpContext
|
||||||
|
) =>
|
||||||
|
{
|
||||||
|
var result = await categoryService.FetchCategory(categoryFilter, pagination);
|
||||||
|
httpContext.Response.Headers["X-Pagination"] = result.Item2.ToString();
|
||||||
|
|
||||||
|
return result.Item1;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
group.MapGet(
|
||||||
|
"categories/tree",
|
||||||
|
async (string? name, CategoryService categoryService) =>
|
||||||
|
{
|
||||||
|
var result = await categoryService.GetAllCategories_Tree(name ?? "");
|
||||||
|
return result.Select(x => Category.ToVM(x)).ToList();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// No Get
|
||||||
|
group.MapGet(
|
||||||
|
"category/{id}",
|
||||||
|
async (Guid id, CategoryService categoryService) =>
|
||||||
|
{
|
||||||
|
return await categoryService.GetCategory(id);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// No Delete
|
||||||
|
group
|
||||||
|
.MapDelete(
|
||||||
|
"category/{id}",
|
||||||
|
async (Guid id, HttpContext httpContext, CategoryService categoryService) =>
|
||||||
|
{
|
||||||
|
var userId = httpContext.User.Claims.First(x => x.Type == "uid").Value;
|
||||||
|
await categoryService.RemoveCategory(id);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.RequireAuthorization();
|
||||||
|
|
||||||
|
// No Put
|
||||||
|
group.MapPut(
|
||||||
|
"category",
|
||||||
|
async ([FromBody] CategoryVM category, CategoryService categoryService) =>
|
||||||
|
{
|
||||||
|
await categoryService.UpdateCategory(category);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// No Post
|
||||||
|
group.MapPost(
|
||||||
|
"category",
|
||||||
|
async ([FromBody] CategoryVM category, CategoryService categoryService) =>
|
||||||
|
{
|
||||||
|
await categoryService.CreateCategory(category);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
using Commerce.Contracts.DTOs;
|
||||||
|
using Commerce.Core.Services;
|
||||||
|
using Generic.Contracts.Generics;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Commerce.Endpoints.v1;
|
||||||
|
|
||||||
|
public static class ProductMap
|
||||||
|
{
|
||||||
|
public static RouteGroupBuilder ProductEndpoints(this RouteGroupBuilder group)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// No Fetch
|
||||||
|
group.MapGet(
|
||||||
|
"products",
|
||||||
|
async (
|
||||||
|
[AsParameters] ProductFilter productFilter,
|
||||||
|
[AsParameters] Pagination pagination,
|
||||||
|
HttpContext httpContext,
|
||||||
|
ProductService productService
|
||||||
|
) =>
|
||||||
|
{
|
||||||
|
var result = await productService.FetchProduct(productFilter, pagination);
|
||||||
|
httpContext.Response.Headers["X-Pagination"] = result.Item2.ToString();
|
||||||
|
|
||||||
|
return result.Item1;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// No Get
|
||||||
|
group.MapGet(
|
||||||
|
"product/{id}",
|
||||||
|
async (Guid id, ProductService productService) =>
|
||||||
|
{
|
||||||
|
return await productService.GetProduct(id);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// No Delete
|
||||||
|
group.MapDelete(
|
||||||
|
"product/{id}",
|
||||||
|
async (Guid id, HttpContext httpContext, ProductService productService) =>
|
||||||
|
{
|
||||||
|
var userId = httpContext.User.Claims.First(x => x.Type == "uid").Value;
|
||||||
|
await productService.RemoveProduct(id);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.RequireAuthorization();
|
||||||
|
|
||||||
|
// No Put
|
||||||
|
group.MapPut(
|
||||||
|
"product",
|
||||||
|
async ([FromBody] ProductVM product, ProductService productService) =>
|
||||||
|
{
|
||||||
|
await productService.UpdateProduct(product);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// No Post
|
||||||
|
group.MapPost(
|
||||||
|
"product",
|
||||||
|
async ([FromBody] ProductVM product, ProductService productService) =>
|
||||||
|
{
|
||||||
|
await productService.CreateProduct(product);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
using Commerce.Config;
|
||||||
|
using Commerce.Endpoints;
|
||||||
|
using Commerce.Contracts.Options;
|
||||||
|
using Commerce.Domain;
|
||||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
|
using Microsoft.AspNetCore.Http.HttpResults;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
|
||||||
|
#pragma warning disable CS0618
|
||||||
|
Npgsql.NpgsqlConnection.GlobalTypeMapper.EnableDynamicJson();
|
||||||
|
#pragma warning restore CS0618
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||||
|
// builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
|
builder.Services.Configure<JWT>(builder.Configuration.GetSection("JWT"));
|
||||||
|
|
||||||
|
// builder.Services.AddDbContext<Context>(
|
||||||
|
// options => options.(builder.Configuration["ConnectionStrings:maria"], ServerVersion.AutoDetect(builder.Configuration["ConnectionStrings:maria"])));
|
||||||
|
|
||||||
|
var connectionString = builder.Configuration.GetConnectionString("PostgreDB");
|
||||||
|
var dataSourceBuilder = new Npgsql.NpgsqlDataSourceBuilder(connectionString);
|
||||||
|
dataSourceBuilder.EnableDynamicJson();
|
||||||
|
var dataSource = dataSourceBuilder.Build();
|
||||||
|
|
||||||
|
builder.Services.AddDbContext<Context>(options =>
|
||||||
|
options.UseNpgsql(dataSource)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// builder.Services.AddCustomCors();
|
||||||
|
|
||||||
|
builder.Services.RegFluentEmail(builder.Configuration);
|
||||||
|
builder.Services.AddCustomCors();
|
||||||
|
builder.Services.AddSwag();
|
||||||
|
builder.Services.Authenticate(builder.Configuration);
|
||||||
|
|
||||||
|
builder.Services.Authorize();
|
||||||
|
builder.Services.RegisterServices();
|
||||||
|
|
||||||
|
// builder.Services.AddAntiforgery();
|
||||||
|
builder.WebHost.ConfigureKestrel(options =>
|
||||||
|
{
|
||||||
|
options.Limits.MaxRequestBodySize = 512 * 1024 * 1024; // 512 MB
|
||||||
|
});
|
||||||
|
|
||||||
|
// Configure form options for multipart body length
|
||||||
|
builder.Services.Configure<FormOptions>(options =>
|
||||||
|
{
|
||||||
|
options.MultipartBodyLengthLimit = 512 * 1024 * 1024; // 512 MB
|
||||||
|
});
|
||||||
|
|
||||||
|
// builder.WebHost.UseUrls("http://*:80"); // Explicit HTTP binding
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
using (var scope = app.Services.CreateScope())
|
||||||
|
{
|
||||||
|
var db = scope.ServiceProvider.GetRequiredService<Context>();
|
||||||
|
db.Database.Migrate(); // Applies pending migrations
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (args.Contains("--migrate"))
|
||||||
|
// {
|
||||||
|
// using var scope = app.Services.CreateScope();
|
||||||
|
// var db = scope.ServiceProvider.GetRequiredService<Context>();
|
||||||
|
// db.Database.Migrate();
|
||||||
|
// }
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
app.UseCors("default");
|
||||||
|
app.UseAuthentication();
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
// if (app.Environment.IsDevelopment())
|
||||||
|
// {
|
||||||
|
// app.UseSwagger();
|
||||||
|
// app.UseSwaggerUI();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// app.UseAntiforgery();
|
||||||
|
|
||||||
|
// app.UseHttpsRedirection();
|
||||||
|
app.MapOpenApi();
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwag();
|
||||||
|
}
|
||||||
|
app.MapAPIv1();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:20864",
|
||||||
|
"sslPort": 44342
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "http://localhost:2001",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"applicationUrl": "https://localhost:7153;http://localhost:5141",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
Using launch settings from /mnt/Dataa/Work/Programming/MainProgram/Backend/APIs/Commerce/Commerce.API/Properties/launchSettings.json...
|
||||||
|
Building...
|
||||||
|
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
|
||||||
|
Executed DbCommand (22ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
|
||||||
|
SELECT "MigrationId", "ProductVersion"
|
||||||
|
FROM "__EFMigrationsHistory"
|
||||||
|
ORDER BY "MigrationId";
|
||||||
|
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
|
||||||
|
Executed DbCommand (11ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
|
||||||
|
CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" (
|
||||||
|
"MigrationId" character varying(150) NOT NULL,
|
||||||
|
"ProductVersion" character varying(32) NOT NULL,
|
||||||
|
CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId")
|
||||||
|
);
|
||||||
|
info: Microsoft.EntityFrameworkCore.Migrations[20411]
|
||||||
|
Acquiring an exclusive lock for migration application. See https://aka.ms/efcore-docs-migrations-lock for more information if this takes too long.
|
||||||
|
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
|
||||||
|
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
|
||||||
|
LOCK TABLE "__EFMigrationsHistory" IN ACCESS EXCLUSIVE MODE
|
||||||
|
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
|
||||||
|
Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
|
||||||
|
SELECT "MigrationId", "ProductVersion"
|
||||||
|
FROM "__EFMigrationsHistory"
|
||||||
|
ORDER BY "MigrationId";
|
||||||
|
info: Microsoft.EntityFrameworkCore.Migrations[20405]
|
||||||
|
No migrations were applied. The database is already up to date.
|
||||||
|
info: Microsoft.Hosting.Lifetime[14]
|
||||||
|
Now listening on: http://localhost:2001
|
||||||
|
info: Microsoft.Hosting.Lifetime[0]
|
||||||
|
Application started. Press Ctrl+C to shut down.
|
||||||
|
info: Microsoft.Hosting.Lifetime[0]
|
||||||
|
Hosting environment: Development
|
||||||
|
info: Microsoft.Hosting.Lifetime[0]
|
||||||
|
Content root path: /mnt/Dataa/Work/Programming/MainProgram/Backend/APIs/Commerce/Commerce.API
|
||||||
|
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
|
||||||
|
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
|
||||||
|
SELECT count(*)::int
|
||||||
|
FROM "Products" AS p
|
||||||
|
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
|
||||||
|
Executed DbCommand (13ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
|
||||||
|
SELECT p."Id", p."CategoryId", p."CategoryName", p."CodeName", p."Created", p."Description", p."Discount", p."IsBundle", p."Name", p."Photos", p."Price", p."TechnicalDetails"
|
||||||
|
FROM "Products" AS p
|
||||||
|
ORDER BY gen_random_uuid()
|
||||||
|
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
|
||||||
|
Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
|
||||||
|
SELECT count(*)::int
|
||||||
|
FROM "Products" AS p
|
||||||
|
warn: Microsoft.EntityFrameworkCore.Query[10102]
|
||||||
|
The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased.
|
||||||
|
warn: Microsoft.EntityFrameworkCore.Query[10102]
|
||||||
|
The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased.
|
||||||
|
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
|
||||||
|
Executed DbCommand (14ms) [Parameters=[@__p_1='?' (DbType = Int32), @__p_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
|
||||||
|
SELECT p."Id", p."CategoryId", p."CategoryName", p."CodeName", p."Created", p."Description", p."Discount", p."IsBundle", p."Name", p."Photos", p."Price", p."TechnicalDetails"
|
||||||
|
FROM "Products" AS p
|
||||||
|
LIMIT @__p_1 OFFSET @__p_0
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"maria": "UserID=root;Password=ama111AMA!!!;Host=localhost;Port=3306;Database=ECommerce;Protocol=TCP;",
|
||||||
|
"PostgreDB": "Host=localhost;Database=ECommerce;Username=test;Password=test;Port=5432;IncludeErrorDetail=true;"
|
||||||
|
},
|
||||||
|
"JWT": {
|
||||||
|
"Key": "thisisasecretKeyIneedtoprovideenoughletterstomakeitwork",
|
||||||
|
"Issuer": "https://hello.com",
|
||||||
|
"Audience": "hello.com",
|
||||||
|
"DurationInMinutes": 10
|
||||||
|
},
|
||||||
|
"EmailTemplate": {
|
||||||
|
"EmailConfirmation": "placeHolder",
|
||||||
|
"ResetPassword": "placeHolder"
|
||||||
|
},
|
||||||
|
"hostname": "placeHolder",
|
||||||
|
"MailSettings": {
|
||||||
|
"Mail": "merge1942@gmail.com",
|
||||||
|
"DisplayName": "Merge",
|
||||||
|
"UserName": "merge1942@gmail.com",
|
||||||
|
"Password": "ftyqwyqpqtixalxp",
|
||||||
|
"Host": "smtp.gmail.com",
|
||||||
|
"Port": 587
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"maria": "UserID=root;Password=ama111AMA!!!;Host=localhost;Port=3306;Database=ECommerce;Protocol=TCP;",
|
||||||
|
"PostgreDB": "Host=localhost;Database=ECommerce;Username=test;Password=test;Port=5432;"
|
||||||
|
},
|
||||||
|
"Domain": "https://api.mass-tech.net",
|
||||||
|
"JWT": {
|
||||||
|
"Key": "thisisasecretKeyIneedtoprovideenoughletterstomakeitwork",
|
||||||
|
"Issuer": "https://hello.com",
|
||||||
|
"Audience": "hello.com",
|
||||||
|
"DurationInMinutes": 10
|
||||||
|
},
|
||||||
|
"EmailTemplate": {
|
||||||
|
"EmailConfirmation": "placeHolder",
|
||||||
|
"ResetPassword": "placeHolder"
|
||||||
|
},
|
||||||
|
"hostname": "placeHolder",
|
||||||
|
"MailSettings": {
|
||||||
|
"Mail": "merge1942@gmail.com",
|
||||||
|
"DisplayName": "Merge",
|
||||||
|
"UserName": "merge1942@gmail.com",
|
||||||
|
"Password": "ftyqwyqpqtixalxp",
|
||||||
|
"Host": "smtp.gmail.com",
|
||||||
|
"Port": 587
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"tfm": "net10.0",
|
||||||
|
"frameworks": [
|
||||||
|
{
|
||||||
|
"name": "Microsoft.NETCore.App",
|
||||||
|
"version": "10.0.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Microsoft.AspNetCore.App",
|
||||||
|
"version": "10.0.0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configProperties": {
|
||||||
|
"System.GC.Server": true,
|
||||||
|
"System.Reflection.NullabilityInfoContext.IsSupported": true,
|
||||||
|
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"tfm": "net10.0",
|
||||||
|
"frameworks": [
|
||||||
|
{
|
||||||
|
"name": "Microsoft.NETCore.App",
|
||||||
|
"version": "10.0.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Microsoft.AspNetCore.App",
|
||||||
|
"version": "10.0.0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configProperties": {
|
||||||
|
"System.GC.Server": true,
|
||||||
|
"System.Reflection.NullabilityInfoContext.IsSupported": true,
|
||||||
|
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
File diff suppressed because one or more lines are too long
+1
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Commerce/ECommerce/ECommerce.API/bin/Debug/net10.0/Microsoft.AspNetCore.Authentication.JwtBearer.dll
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"maria": "UserID=root;Password=ama111AMA!!!;Host=localhost;Port=3306;Database=ECommerce;Protocol=TCP;",
|
||||||
|
"PostgreDB": "Host=localhost;Database=ECommerce;Username=test;Password=test;Port=5432;IncludeErrorDetail=true;"
|
||||||
|
},
|
||||||
|
"JWT": {
|
||||||
|
"Key": "thisisasecretKeyIneedtoprovideenoughletterstomakeitwork",
|
||||||
|
"Issuer": "https://hello.com",
|
||||||
|
"Audience": "hello.com",
|
||||||
|
"DurationInMinutes": 10
|
||||||
|
},
|
||||||
|
"EmailTemplate": {
|
||||||
|
"EmailConfirmation": "placeHolder",
|
||||||
|
"ResetPassword": "placeHolder"
|
||||||
|
},
|
||||||
|
"hostname": "placeHolder",
|
||||||
|
"MailSettings": {
|
||||||
|
"Mail": "merge1942@gmail.com",
|
||||||
|
"DisplayName": "Merge",
|
||||||
|
"UserName": "merge1942@gmail.com",
|
||||||
|
"Password": "ftyqwyqpqtixalxp",
|
||||||
|
"Host": "smtp.gmail.com",
|
||||||
|
"Port": 587
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"maria": "UserID=root;Password=ama111AMA!!!;Host=localhost;Port=3306;Database=ECommerce;Protocol=TCP;",
|
||||||
|
"PostgreDB": "Host=localhost;Database=ECommerce;Username=test;Password=test;Port=5432;"
|
||||||
|
},
|
||||||
|
"Domain": "https://api.mass-tech.net",
|
||||||
|
"JWT": {
|
||||||
|
"Key": "thisisasecretKeyIneedtoprovideenoughletterstomakeitwork",
|
||||||
|
"Issuer": "https://hello.com",
|
||||||
|
"Audience": "hello.com",
|
||||||
|
"DurationInMinutes": 10
|
||||||
|
},
|
||||||
|
"EmailTemplate": {
|
||||||
|
"EmailConfirmation": "placeHolder",
|
||||||
|
"ResetPassword": "placeHolder"
|
||||||
|
},
|
||||||
|
"hostname": "placeHolder",
|
||||||
|
"MailSettings": {
|
||||||
|
"Mail": "merge1942@gmail.com",
|
||||||
|
"DisplayName": "Merge",
|
||||||
|
"UserName": "merge1942@gmail.com",
|
||||||
|
"Password": "ftyqwyqpqtixalxp",
|
||||||
|
"Host": "smtp.gmail.com",
|
||||||
|
"Port": 587
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user