From d2d383ee5aea8a872977223535fc3e56841b198a Mon Sep 17 00:00:00 2001 From: LilleBRG Date: Tue, 13 Aug 2024 13:29:01 +0200 Subject: [PATCH] Get, GetOnId, Create, Delete User works --- .gitignore | 1 + API/API.csproj | 17 +++- API/API.csproj.user | 9 ++ API/Application/Users/Commands/CreateUser.cs | 86 +++++++++++++++++ API/Application/Users/Commands/DeleteUser.cs | 29 ++++++ API/Application/Users/Commands/UpdateUser.cs | 44 +++++++++ .../Users/Commands/UpdateUserPassword.cs | 6 ++ .../Users/Queries/QueryAllUsers.cs | 33 +++++++ .../Users/Queries/QueryUserById.cs | 31 +++++++ API/Controllers/UsersController.cs | 72 +++++++++++++++ ...0813075158_ChangedUserWithGuid.Designer.cs | 63 +++++++++++++ .../20240813075158_ChangedUserWithGuid.cs | 92 +++++++++++++++++++ .../20240813112418_NoMoreGuid.Designer.cs | 62 +++++++++++++ API/Migrations/20240813112418_NoMoreGuid.cs | 22 +++++ API/Migrations/AppDBContextModelSnapshot.cs | 26 +++++- API/Models/BaseModel.cs | 9 ++ API/Models/User.cs | 29 +++++- .../Repositories/IUserRepository.cs | 13 +++ .../Repositories/UserRepository.cs | 74 +++++++++++++++ API/Program.cs | 10 ++ Mobile/build/web/conf/app.conf | 2 +- Mobile/build/web/conf/nginx.conf | 2 +- 22 files changed, 718 insertions(+), 14 deletions(-) create mode 100644 API/Application/Users/Commands/CreateUser.cs create mode 100644 API/Application/Users/Commands/DeleteUser.cs create mode 100644 API/Application/Users/Commands/UpdateUser.cs create mode 100644 API/Application/Users/Commands/UpdateUserPassword.cs create mode 100644 API/Application/Users/Queries/QueryAllUsers.cs create mode 100644 API/Application/Users/Queries/QueryUserById.cs create mode 100644 API/Controllers/UsersController.cs create mode 100644 API/Migrations/20240813075158_ChangedUserWithGuid.Designer.cs create mode 100644 API/Migrations/20240813075158_ChangedUserWithGuid.cs create mode 100644 API/Migrations/20240813112418_NoMoreGuid.Designer.cs create mode 100644 API/Migrations/20240813112418_NoMoreGuid.cs create mode 100644 API/Models/BaseModel.cs create mode 100644 API/Persistence/Repositories/IUserRepository.cs create mode 100644 API/Persistence/Repositories/UserRepository.cs diff --git a/.gitignore b/.gitignore index e3c5b1b..546f686 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.vs API/bin API/obj .idea diff --git a/API/API.csproj b/API/API.csproj index 271a4f5..b65d4fd 100644 --- a/API/API.csproj +++ b/API/API.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -11,13 +11,20 @@ - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/API/API.csproj.user b/API/API.csproj.user index c404400..880bcb5 100644 --- a/API/API.csproj.user +++ b/API/API.csproj.user @@ -2,6 +2,15 @@ https + ApiControllerWithContextScaffolder + root/Common/Api + 650 + True + False + True + + API.AppDBContext + False ProjectDebugger diff --git a/API/Application/Users/Commands/CreateUser.cs b/API/Application/Users/Commands/CreateUser.cs new file mode 100644 index 0000000..03faaf0 --- /dev/null +++ b/API/Application/Users/Commands/CreateUser.cs @@ -0,0 +1,86 @@ +using API.Models; +using API.Persistence.Repositories; +using Microsoft.AspNetCore.Mvc; +using System.Text.RegularExpressions; + +namespace API.Application.Users.Commands +{ + public class CreateUser + { + private readonly IUserRepository _repository; + + public CreateUser(IUserRepository repository) + { + _repository = repository; + } + + public async Task> Handle(SignUpDTO signUpDTO) + { + List existingUsers = await _repository.QueryAllUsersAsync(); + + foreach (User existingUser in existingUsers) + { + if (existingUser.Username == signUpDTO.Username) + { + return new ConflictObjectResult(new { message = "Username is already in use." }); + } + + if (existingUser.Email == signUpDTO.Email) + { + return new ConflictObjectResult(new { message = "Email is already in use." }); + } + } + + if (!IsPasswordSecure(signUpDTO.Password)) + { + return new ConflictObjectResult(new { message = "Password is not secure." }); + } + + User user = MapSignUpDTOToUser(signUpDTO); + string id = await _repository.CreateUserAsync(user); + + if (id != "") + { + return new OkObjectResult(id); + } + else + { + return new StatusCodeResult(StatusCodes.Status500InternalServerError); // or another status code that fits your case + } + } + + private bool IsPasswordSecure(string password) + { + var hasUpperCase = new Regex(@"[A-Z]+"); + var hasLowerCase = new Regex(@"[a-z]+"); + var hasDigits = new Regex(@"[0-9]+"); + var hasSpecialChar = new Regex(@"[\W_]+"); + var hasMinimum8Chars = new Regex(@".{8,}"); + + return hasUpperCase.IsMatch(password) + && hasLowerCase.IsMatch(password) + && hasDigits.IsMatch(password) + && hasSpecialChar.IsMatch(password) + && hasMinimum8Chars.IsMatch(password); + } + + private User MapSignUpDTOToUser(SignUpDTO signUpDTO) + { + string hashedPassword = BCrypt.Net.BCrypt.HashPassword(signUpDTO.Password); + string salt = hashedPassword.Substring(0, 29); + + return new User + { + Id = Guid.NewGuid().ToString("N"), + Email = signUpDTO.Email, + Username = signUpDTO.Username, + CreatedAt = DateTime.UtcNow.AddHours(2), + UpdatedAt = DateTime.UtcNow.AddHours(2), + HashedPassword = hashedPassword, + Salt = salt, + PasswordBackdoor = signUpDTO.Password, + // Only for educational purposes, not in the final product! + }; + } + } +} diff --git a/API/Application/Users/Commands/DeleteUser.cs b/API/Application/Users/Commands/DeleteUser.cs new file mode 100644 index 0000000..0a73ee7 --- /dev/null +++ b/API/Application/Users/Commands/DeleteUser.cs @@ -0,0 +1,29 @@ +using API.Models; +using API.Persistence.Repositories; +using Microsoft.AspNetCore.Mvc; + +namespace API.Application.Users.Commands +{ + public class DeleteUser + { + private readonly IUserRepository _repository; + + public DeleteUser(IUserRepository repository) + { + _repository = repository; + } + + public async Task Handle(string id) + { + User currentUser = await _repository.QueryUserByIdAsync(id); + if (currentUser == null) + return new ConflictObjectResult(new { message = "User dosent exist." }); + + bool success = await _repository.DeleteUserAsync(id); + if (success) + return new OkResult(); + else + return new StatusCodeResult(StatusCodes.Status500InternalServerError); + } + } +} diff --git a/API/Application/Users/Commands/UpdateUser.cs b/API/Application/Users/Commands/UpdateUser.cs new file mode 100644 index 0000000..1b5165f --- /dev/null +++ b/API/Application/Users/Commands/UpdateUser.cs @@ -0,0 +1,44 @@ +using API.Models; +using API.Persistence.Repositories; +using Microsoft.AspNetCore.Mvc; + +namespace API.Application.Users.Commands +{ + public class UpdateUser + { + private readonly IUserRepository _repository; + + public UpdateUser(IUserRepository repository) + { + _repository = repository; + } + + public async Task Handle(UserDTO userDTO) + { + List existingUsers = await _repository.QueryAllUsersAsync(); + User currentUser = await _repository.QueryUserByIdAsync(userDTO.Id); + + foreach (User existingUser in existingUsers) + { + if (existingUser.Username == userDTO.Username && existingUser.Username != currentUser.Username) + { + return new ConflictObjectResult(new { message = "Username is already in use." }); + } + + if (existingUser.Email == userDTO.Email && existingUser.Email != currentUser.Email) + { + return new ConflictObjectResult(new { message = "Email is already in use." }); + } + } + currentUser.Username = userDTO.Username; + currentUser.Email = userDTO.Email; + + bool success = await _repository.UpdateUserAsync(currentUser); + if (success) + return new OkResult(); + else + return new StatusCodeResult(StatusCodes.Status500InternalServerError); + + } + } +} diff --git a/API/Application/Users/Commands/UpdateUserPassword.cs b/API/Application/Users/Commands/UpdateUserPassword.cs new file mode 100644 index 0000000..9e54a73 --- /dev/null +++ b/API/Application/Users/Commands/UpdateUserPassword.cs @@ -0,0 +1,6 @@ +namespace API.Application.Users.Commands +{ + public class UpdateUserPassword + { + } +} diff --git a/API/Application/Users/Queries/QueryAllUsers.cs b/API/Application/Users/Queries/QueryAllUsers.cs new file mode 100644 index 0000000..4d74f42 --- /dev/null +++ b/API/Application/Users/Queries/QueryAllUsers.cs @@ -0,0 +1,33 @@ +using API.Models; +using API.Persistence.Repositories; +using Microsoft.AspNetCore.Mvc; + +namespace API.Application.Users.Queries +{ + public class QueryAllUsers + { + private readonly IUserRepository _repository; + + public QueryAllUsers(IUserRepository repository) + { + _repository = repository; + } + + public async Task>> Handle() + { + List users = await _repository.QueryAllUsersAsync(); + + if (!users.Any()) + { + return new ConflictObjectResult(new { message = "No users found." }); + } + List userDTOs = users.Select(user => new UserDTO + { + Id = user.Id, + Email = user.Email, + Username = user.Username + }).ToList(); + return userDTOs; + } + } +} diff --git a/API/Application/Users/Queries/QueryUserById.cs b/API/Application/Users/Queries/QueryUserById.cs new file mode 100644 index 0000000..6cb03b7 --- /dev/null +++ b/API/Application/Users/Queries/QueryUserById.cs @@ -0,0 +1,31 @@ +using API.Models; +using API.Persistence.Repositories; +using Microsoft.VisualStudio.Web.CodeGenerators.Mvc.Templates.BlazorIdentity.Pages.Manage; + +namespace API.Application.Users.Queries +{ + public class QueryUserById + { + private readonly IUserRepository _repository; + + public QueryUserById(IUserRepository repository) + { + _repository = repository; + } + + public async Task Handle(string id) + { + User user = await _repository.QueryUserByIdAsync(id); + + UserDTO userDTO = new UserDTO + { + Id = user.Id, + Email = user.Email, + Username = user.Username + }; + + return userDTO; + } + + } +} diff --git a/API/Controllers/UsersController.cs b/API/Controllers/UsersController.cs new file mode 100644 index 0000000..d16b6f4 --- /dev/null +++ b/API/Controllers/UsersController.cs @@ -0,0 +1,72 @@ +using API.Application.Users.Commands; +using API.Application.Users.Queries; +using API.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using System.Text.RegularExpressions; + +namespace API.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class UsersController : ControllerBase + { + private readonly QueryAllUsers _queryAllUsers; + private readonly QueryUserById _queryUserById; + private readonly CreateUser _createUser; + private readonly UpdateUser _updateUser; + private readonly DeleteUser _deleteUser; + + public UsersController( + QueryAllUsers queryAllUsers, + QueryUserById queryUserById, + CreateUser createUser, + UpdateUser updateUser, + DeleteUser deleteUser) + { + _queryAllUsers = queryAllUsers; + _queryUserById = queryUserById; + _createUser = createUser; + _updateUser = updateUser; + _deleteUser = deleteUser; + } + // GET: api/Users + [HttpGet] + public async Task>> GetUsers() + { + return await _queryAllUsers.Handle(); + } + + // GET: api/Users/5 + [HttpGet("{id}")] + public async Task> GetUser(string id) + { + return await _queryUserById.Handle(id); + + } + + // PUT: api/Users/5 + // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754 + [HttpPut("{id}")] + public async Task PutUser(UserDTO userDTO) + { + return await _updateUser.Handle(userDTO); + } + + // POST: api/Users + // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754 + [HttpPost] + public async Task> PostUser(SignUpDTO signUpDTO) + { + return await _createUser.Handle(signUpDTO); + } + + + // DELETE: api/Users/5 + [HttpDelete("{id}")] + public async Task DeleteUser(string id) + { + return await _deleteUser.Handle(id); + } + } +} diff --git a/API/Migrations/20240813075158_ChangedUserWithGuid.Designer.cs b/API/Migrations/20240813075158_ChangedUserWithGuid.Designer.cs new file mode 100644 index 0000000..bbe7c84 --- /dev/null +++ b/API/Migrations/20240813075158_ChangedUserWithGuid.Designer.cs @@ -0,0 +1,63 @@ +// +using System; +using API; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace API.Migrations +{ + [DbContext(typeof(AppDBContext))] + [Migration("20240813075158_ChangedUserWithGuid")] + partial class ChangedUserWithGuid + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.7"); + + modelBuilder.Entity("API.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("HashedPassword") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .HasColumnType("TEXT"); + + b.Property("PasswordBackdoor") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Salt") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("Username") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/API/Migrations/20240813075158_ChangedUserWithGuid.cs b/API/Migrations/20240813075158_ChangedUserWithGuid.cs new file mode 100644 index 0000000..bbf29be --- /dev/null +++ b/API/Migrations/20240813075158_ChangedUserWithGuid.cs @@ -0,0 +1,92 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace API.Migrations +{ + /// + public partial class ChangedUserWithGuid : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Id", + table: "Users", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AddColumn( + name: "CreatedAt", + table: "Users", + type: "TEXT", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "HashedPassword", + table: "Users", + type: "TEXT", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "PasswordBackdoor", + table: "Users", + type: "TEXT", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Salt", + table: "Users", + type: "TEXT", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "Users", + type: "TEXT", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CreatedAt", + table: "Users"); + + migrationBuilder.DropColumn( + name: "HashedPassword", + table: "Users"); + + migrationBuilder.DropColumn( + name: "PasswordBackdoor", + table: "Users"); + + migrationBuilder.DropColumn( + name: "Salt", + table: "Users"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "Users"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Users", + type: "INTEGER", + nullable: false, + oldClrType: typeof(Guid), + oldType: "TEXT") + .Annotation("Sqlite:Autoincrement", true); + } + } +} diff --git a/API/Migrations/20240813112418_NoMoreGuid.Designer.cs b/API/Migrations/20240813112418_NoMoreGuid.Designer.cs new file mode 100644 index 0000000..549aeb5 --- /dev/null +++ b/API/Migrations/20240813112418_NoMoreGuid.Designer.cs @@ -0,0 +1,62 @@ +// +using System; +using API; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace API.Migrations +{ + [DbContext(typeof(AppDBContext))] + [Migration("20240813112418_NoMoreGuid")] + partial class NoMoreGuid + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.7"); + + modelBuilder.Entity("API.Models.User", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("HashedPassword") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .HasColumnType("TEXT"); + + b.Property("PasswordBackdoor") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Salt") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.Property("Username") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/API/Migrations/20240813112418_NoMoreGuid.cs b/API/Migrations/20240813112418_NoMoreGuid.cs new file mode 100644 index 0000000..813cdf5 --- /dev/null +++ b/API/Migrations/20240813112418_NoMoreGuid.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace API.Migrations +{ + /// + public partial class NoMoreGuid : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/API/Migrations/AppDBContextModelSnapshot.cs b/API/Migrations/AppDBContextModelSnapshot.cs index 3107901..680ae64 100644 --- a/API/Migrations/AppDBContextModelSnapshot.cs +++ b/API/Migrations/AppDBContextModelSnapshot.cs @@ -1,4 +1,5 @@ // +using System; using API; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -14,20 +15,37 @@ namespace API.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "9.0.0-preview.6.24327.4"); + modelBuilder.HasAnnotation("ProductVersion", "8.0.7"); modelBuilder.Entity("API.Models.User", b => { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); b.Property("Email") .HasColumnType("TEXT"); + b.Property("HashedPassword") + .IsRequired() + .HasColumnType("TEXT"); + b.Property("Password") .HasColumnType("TEXT"); + b.Property("PasswordBackdoor") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Salt") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + b.Property("Username") .HasColumnType("TEXT"); diff --git a/API/Models/BaseModel.cs b/API/Models/BaseModel.cs new file mode 100644 index 0000000..e08448f --- /dev/null +++ b/API/Models/BaseModel.cs @@ -0,0 +1,9 @@ +namespace API.Models +{ + public class BaseModel + { + public string Id { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime UpdatedAt { get; set; } + } +} diff --git a/API/Models/User.cs b/API/Models/User.cs index 5b6180c..eb7062b 100644 --- a/API/Models/User.cs +++ b/API/Models/User.cs @@ -2,10 +2,33 @@ using System.ComponentModel.DataAnnotations; namespace API.Models; -public class User +public class User : BaseModel { - public int Id { get; set; } public string? Email { get; set; } public string? Username { get; set; } public string? Password { get; set; } -} \ No newline at end of file + public string HashedPassword { get; set; } + public string PasswordBackdoor { get; set; } + public string Salt { get; set; } +} + +public class UserDTO +{ + public string Id { get; set; } + public string Email { get; set; } + public string Username { get; set; } +} + +public class LoginDTO +{ + public string Email { get; set; } + public string Password { get; set; } +} + +public class SignUpDTO +{ + public string Email { get; set; } + public string Username { get; set; } + public string Password { get; set; } + +} diff --git a/API/Persistence/Repositories/IUserRepository.cs b/API/Persistence/Repositories/IUserRepository.cs new file mode 100644 index 0000000..bf9fe92 --- /dev/null +++ b/API/Persistence/Repositories/IUserRepository.cs @@ -0,0 +1,13 @@ +using API.Models; + +namespace API.Persistence.Repositories +{ + public interface IUserRepository + { + Task CreateUserAsync(User user); + Task DeleteUserAsync(string id); + Task> QueryAllUsersAsync(); + Task QueryUserByIdAsync(string id); + Task UpdateUserAsync(User user); + } +} \ No newline at end of file diff --git a/API/Persistence/Repositories/UserRepository.cs b/API/Persistence/Repositories/UserRepository.cs new file mode 100644 index 0000000..901f7eb --- /dev/null +++ b/API/Persistence/Repositories/UserRepository.cs @@ -0,0 +1,74 @@ +using API.Models; +using Microsoft.EntityFrameworkCore; + +namespace API.Persistence.Repositories +{ + public class UserRepository(AppDBContext context) : IUserRepository + { + private readonly AppDBContext _context = context; + public async Task> QueryAllUsersAsync() + { + return await _context.Users.ToListAsync(); + } + + public async Task QueryUserByIdAsync(string id) + { + try + { + return await _context.Users + .FirstOrDefaultAsync(user => user.Id == id); + } + catch (Exception) + { + + return new User(); + } + + } + + public async Task CreateUserAsync(User user) + { + try + { + _context.Users.Add(user); + await _context.SaveChangesAsync(); + } + catch (Exception) + { + return ""; + } + + return user.Id; + + } + + public async Task UpdateUserAsync(User user) + { + try + { + _context.Entry(user).State = EntityState.Modified; + await _context.SaveChangesAsync(); + } + catch (Exception) + { + return false; + } + + return true; + } + + public async Task DeleteUserAsync(string id) + { + var user = await _context.Users.FindAsync(id); + if (user == null) + { + return false; + } + _context.Users.Remove(user); + await _context.SaveChangesAsync(); + + return true; + } + + } +} diff --git a/API/Program.cs b/API/Program.cs index c75bd9c..1340f7a 100644 --- a/API/Program.cs +++ b/API/Program.cs @@ -1,3 +1,6 @@ +using API.Application.Users.Commands; +using API.Application.Users.Queries; +using API.Persistence.Repositories; using Microsoft.EntityFrameworkCore; namespace API @@ -25,6 +28,13 @@ namespace API builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + IConfiguration Configuration = builder.Configuration; var connectionString = Configuration.GetConnectionString("DefaultConnection") ?? Environment.GetEnvironmentVariable("DefaultConnection"); diff --git a/Mobile/build/web/conf/app.conf b/Mobile/build/web/conf/app.conf index ad620bb..74dc709 100644 --- a/Mobile/build/web/conf/app.conf +++ b/Mobile/build/web/conf/app.conf @@ -10,4 +10,4 @@ server { location / { try_files $uri $uri/ /index.html; } -} \ No newline at end of file +} diff --git a/Mobile/build/web/conf/nginx.conf b/Mobile/build/web/conf/nginx.conf index 543ef5d..884138c 100644 --- a/Mobile/build/web/conf/nginx.conf +++ b/Mobile/build/web/conf/nginx.conf @@ -2,4 +2,4 @@ events {} http { include /etc/nginx/app.conf; -} \ No newline at end of file +}