diff --git a/HR.LeaveManagement.BlazorUI/Pages/LeaveTypes/Index.razor b/HR.LeaveManagement.BlazorUI/Pages/LeaveTypes/Index.razor
index 699495e..de6006b 100644
--- a/HR.LeaveManagement.BlazorUI/Pages/LeaveTypes/Index.razor
+++ b/HR.LeaveManagement.BlazorUI/Pages/LeaveTypes/Index.razor
@@ -1,5 +1,7 @@
@page "/leavetypes/"
+
diff --git a/HR.LeaveManagement.BlazorUI/Pages/Login.razor b/HR.LeaveManagement.BlazorUI/Pages/Login.razor
index fdf5acd..8850b5b 100644
--- a/HR.LeaveManagement.BlazorUI/Pages/Login.razor
+++ b/HR.LeaveManagement.BlazorUI/Pages/Login.razor
@@ -1,5 +1,7 @@
@page "/login"
+
Login
+
Login
@if (string.IsNullOrEmpty(Message) == false)
{
diff --git a/HR.LeaveManagement.BlazorUI/Pages/Register.razor b/HR.LeaveManagement.BlazorUI/Pages/Register.razor
index 212d9f9..9b23347 100644
--- a/HR.LeaveManagement.BlazorUI/Pages/Register.razor
+++ b/HR.LeaveManagement.BlazorUI/Pages/Register.razor
@@ -1,5 +1,7 @@
@page "/register"
+
Register
+
Register
@if (string.IsNullOrEmpty(Message) == false)
diff --git a/HR.LeaveManagement.BlazorUI/Shared/MainLayout.razor.css b/HR.LeaveManagement.BlazorUI/Shared/MainLayout.razor.css
index e9459c5..ed1d27f 100644
--- a/HR.LeaveManagement.BlazorUI/Shared/MainLayout.razor.css
+++ b/HR.LeaveManagement.BlazorUI/Shared/MainLayout.razor.css
@@ -56,7 +56,7 @@ main {
}
.sidebar {
- width: 250px;
+ width: 290px;
height: 100vh;
position: sticky;
top: 0;
diff --git a/HR.LeaveManagement.BlazorUI/Shared/NavMenu.razor b/HR.LeaveManagement.BlazorUI/Shared/NavMenu.razor
index 1548211..102e9a3 100644
--- a/HR.LeaveManagement.BlazorUI/Shared/NavMenu.razor
+++ b/HR.LeaveManagement.BlazorUI/Shared/NavMenu.razor
@@ -1,6 +1,6 @@
-
HR.LeaveManagement.BlazorUI
+
HR Leave Management System
@@ -76,4 +76,4 @@
{
collapseNavMenu = !collapseNavMenu;
}
-}
+}
\ No newline at end of file
diff --git a/HR.LeaveManagement.BlazorUI/_Imports.razor b/HR.LeaveManagement.BlazorUI/_Imports.razor
index 7c5d435..a421fcc 100644
--- a/HR.LeaveManagement.BlazorUI/_Imports.razor
+++ b/HR.LeaveManagement.BlazorUI/_Imports.razor
@@ -7,4 +7,10 @@
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using HR.LeaveManagement.BlazorUI
+@using HR.LeaveManagement.BlazorUI.Pages.LeaveTypes
@using HR.LeaveManagement.BlazorUI.Shared
+@using HR.LeaveManagement.BlazorUI.Models
+@using Microsoft.AspNetCore.Components.Authorization
+@using Microsoft.AspNetCore.Authorization;
+@using Blazored.Toast
+@using Blazored.Toast.Services
\ No newline at end of file
diff --git a/HR.LeaveManagement.Identity/Configurations/RoleConfiguration.cs b/HR.LeaveManagement.Identity/Configurations/RoleConfiguration.cs
new file mode 100644
index 0000000..300394d
--- /dev/null
+++ b/HR.LeaveManagement.Identity/Configurations/RoleConfiguration.cs
@@ -0,0 +1,25 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace HR.LeaveManagement.Identity.Configurations;
+public class RoleConfiguration : IEntityTypeConfiguration
+{
+ public void Configure(EntityTypeBuilder builder)
+ {
+ builder.HasData(
+ new IdentityRole
+ {
+ Id = "cac43a6e-f7bb-4448-baaf-1add431ccbbf",
+ Name = "Employee",
+ NormalizedName = "EMPLOYEE"
+ },
+ new IdentityRole
+ {
+ Id = "cbc43a8e-f7bb-4445-baaf-1add431ffbbf",
+ Name = "Administrator",
+ NormalizedName = "ADMINISTRATOR"
+ }
+ );
+ }
+}
\ No newline at end of file
diff --git a/HR.LeaveManagement.Identity/Configurations/UserConfiguration.cs b/HR.LeaveManagement.Identity/Configurations/UserConfiguration.cs
new file mode 100644
index 0000000..8cdc4af
--- /dev/null
+++ b/HR.LeaveManagement.Identity/Configurations/UserConfiguration.cs
@@ -0,0 +1,40 @@
+using HR.LeaveManagement.Identity.Models;
+
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace HR.LeaveManagement.Identity.Configurations;
+public class UserConfiguration : IEntityTypeConfiguration
+{
+ public void Configure(EntityTypeBuilder builder)
+ {
+ var hasher = new PasswordHasher();
+ builder.HasData(
+ new ApplicationUser
+ {
+ Id = "8e445865-a24d-4543-a6c6-9443d048cdb9",
+ Email = "admin@localhost.com",
+ NormalizedEmail = "ADMIN@LOCALHOST.COM",
+ FirstName = "System",
+ LastName = "Admin",
+ UserName = "admin@localhost.com",
+ NormalizedUserName = "ADMIN@LOCALHOST.COM",
+ PasswordHash = hasher.HashPassword(null, "P@ssword1"),
+ EmailConfirmed = true
+ },
+ new ApplicationUser
+ {
+ Id = "9e224968-33e4-4652-b7b7-8574d048cdb9",
+ Email = "user@localhost.com",
+ NormalizedEmail = "USER@LOCALHOST.COM",
+ FirstName = "System",
+ LastName = "User",
+ UserName = "user@localhost.com",
+ NormalizedUserName = "USER@LOCALHOST.COM",
+ PasswordHash = hasher.HashPassword(null, "P@ssword1"),
+ EmailConfirmed = true
+ }
+ );
+ }
+}
\ No newline at end of file
diff --git a/HR.LeaveManagement.Identity/Configurations/UserRoleConfiguration.cs b/HR.LeaveManagement.Identity/Configurations/UserRoleConfiguration.cs
new file mode 100644
index 0000000..32839d9
--- /dev/null
+++ b/HR.LeaveManagement.Identity/Configurations/UserRoleConfiguration.cs
@@ -0,0 +1,23 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace HR.LeaveManagement.Identity.Configurations;
+public class UserRoleConfiguration : IEntityTypeConfiguration>
+{
+ public void Configure(EntityTypeBuilder> builder)
+ {
+ builder.HasData(
+ new IdentityUserRole
+ {
+ RoleId = "cbc43a8e-f7bb-4445-baaf-1add431ffbbf",
+ UserId = "8e445865-a24d-4543-a6c6-9443d048cdb9"
+ },
+ new IdentityUserRole
+ {
+ RoleId = "cac43a6e-f7bb-4448-baaf-1add431ccbbf",
+ UserId = "9e224968-33e4-4652-b7b7-8574d048cdb9"
+ }
+ );
+ }
+}
\ No newline at end of file
diff --git a/HR.LeaveManagement.Identity/DbContext/HrLeaveManagementIdentityDbContext.cs b/HR.LeaveManagement.Identity/DbContext/HrLeaveManagementIdentityDbContext.cs
new file mode 100644
index 0000000..bd39922
--- /dev/null
+++ b/HR.LeaveManagement.Identity/DbContext/HrLeaveManagementIdentityDbContext.cs
@@ -0,0 +1,19 @@
+using HR.LeaveManagement.Identity.Models;
+
+using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+
+namespace HR.LeaveManagement.Identity.DbContext;
+public class HrLeaveManagementIdentityDbContext : IdentityDbContext
+{
+ public HrLeaveManagementIdentityDbContext(DbContextOptions options)
+ : base(options)
+ {
+ }
+
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ base.OnModelCreating(builder);
+ builder.ApplyConfigurationsFromAssembly(typeof(HrLeaveManagementIdentityDbContext).Assembly);
+ }
+}
\ No newline at end of file
diff --git a/HR.LeaveManagement.Identity/HR.LeaveManagement.Identity.csproj b/HR.LeaveManagement.Identity/HR.LeaveManagement.Identity.csproj
new file mode 100644
index 0000000..bc49dbe
--- /dev/null
+++ b/HR.LeaveManagement.Identity/HR.LeaveManagement.Identity.csproj
@@ -0,0 +1,25 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
diff --git a/HR.LeaveManagement.Identity/IdentityServicesRegistration.cs b/HR.LeaveManagement.Identity/IdentityServicesRegistration.cs
new file mode 100644
index 0000000..1641557
--- /dev/null
+++ b/HR.LeaveManagement.Identity/IdentityServicesRegistration.cs
@@ -0,0 +1,54 @@
+using System.Text;
+
+using HR.LeaveManagement.Application.Contracts.Identity;
+using HR.LeaveManagement.Application.Models.Identity;
+using HR.LeaveManagement.Identity.DbContext;
+using HR.LeaveManagement.Identity.Models;
+using HR.LeaveManagement.Identity.Services;
+
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.IdentityModel.Tokens;
+
+namespace HR.LeaveManagement.Identity;
+public static class IdentityServicesRegistration
+{
+ public static IServiceCollection AddIdentityServices(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.Configure(configuration.GetSection("JwtSettings"));
+
+ services.AddDbContext(options =>
+ options.UseSqlServer(configuration.GetConnectionString("HrDatabaseConnectionString")));
+
+ services.AddIdentity()
+ .AddEntityFrameworkStores().AddDefaultTokenProviders();
+
+ services.AddTransient();
+ services.AddTransient();
+
+ services.AddAuthentication(options =>
+ {
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+ }).AddJwtBearer(o =>
+ {
+ o.TokenValidationParameters = new TokenValidationParameters
+ {
+ ValidateIssuerSigningKey = true,
+ ValidateIssuer = true,
+ ValidateAudience = true,
+ ValidateLifetime = true,
+ ClockSkew = TimeSpan.Zero,
+ ValidIssuer = configuration["JwtSettings:Issuer"],
+ ValidAudience = configuration["JwtSettings:Audience"],
+ IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtSettings:Key"]))
+
+ };
+ });
+
+ return services;
+ }
+}
\ No newline at end of file
diff --git a/HR.LeaveManagement.Identity/Migrations/20230506212044_FreshMigration.Designer.cs b/HR.LeaveManagement.Identity/Migrations/20230506212044_FreshMigration.Designer.cs
new file mode 100644
index 0000000..ff8829a
--- /dev/null
+++ b/HR.LeaveManagement.Identity/Migrations/20230506212044_FreshMigration.Designer.cs
@@ -0,0 +1,351 @@
+//
+using System;
+using HR.LeaveManagement.Identity.DbContext;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace HR.LeaveManagement.Identity.Migrations
+{
+ [DbContext(typeof(HrLeaveManagementIdentityDbContext))]
+ [Migration("20230506212044_FreshMigration")]
+ partial class FreshMigration
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.5")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("HR.LeaveManagement.Identity.Models.ApplicationUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("AccessFailedCount")
+ .HasColumnType("int");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("EmailConfirmed")
+ .HasColumnType("bit");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LockoutEnabled")
+ .HasColumnType("bit");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumberConfirmed")
+ .HasColumnType("bit");
+
+ b.Property("SecurityStamp")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TwoFactorEnabled")
+ .HasColumnType("bit");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex")
+ .HasFilter("[NormalizedUserName] IS NOT NULL");
+
+ b.ToTable("AspNetUsers", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = "8e445865-a24d-4543-a6c6-9443d048cdb9",
+ AccessFailedCount = 0,
+ ConcurrencyStamp = "a2570d94-af87-4332-8260-e2f319be6161",
+ Email = "admin@localhost.com",
+ EmailConfirmed = true,
+ FirstName = "System",
+ LastName = "Admin",
+ LockoutEnabled = false,
+ NormalizedEmail = "ADMIN@LOCALHOST.COM",
+ NormalizedUserName = "ADMIN@LOCALHOST.COM",
+ PasswordHash = "AQAAAAIAAYagAAAAEChVlq6vGrjrmWbU3Ut9HAfRfCywAkTDyqPT86JiI7EIrw1U0w9/QwkSBOzbHdsheg==",
+ PhoneNumberConfirmed = false,
+ SecurityStamp = "9ad661f8-99c1-4411-a244-ab6b00c08e17",
+ TwoFactorEnabled = false,
+ UserName = "admin@localhost.com"
+ },
+ new
+ {
+ Id = "9e224968-33e4-4652-b7b7-8574d048cdb9",
+ AccessFailedCount = 0,
+ ConcurrencyStamp = "1eed0d78-0687-4f5e-888a-5adbee444629",
+ Email = "user@localhost.com",
+ EmailConfirmed = true,
+ FirstName = "System",
+ LastName = "User",
+ LockoutEnabled = false,
+ NormalizedEmail = "USER@LOCALHOST.COM",
+ NormalizedUserName = "USER@LOCALHOST.COM",
+ PasswordHash = "AQAAAAIAAYagAAAAEL+FDtu/R9TJijETo1GohRaWxlcTBz6+E7KVAH3ITJjEdzbmjMziyxxtlodn56NDXA==",
+ PhoneNumberConfirmed = false,
+ SecurityStamp = "0c8d038a-9388-48ac-8aca-ff749e09e078",
+ TwoFactorEnabled = false,
+ UserName = "user@localhost.com"
+ });
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex")
+ .HasFilter("[NormalizedName] IS NOT NULL");
+
+ b.ToTable("AspNetRoles", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = "cac43a6e-f7bb-4448-baaf-1add431ccbbf",
+ Name = "Employee",
+ NormalizedName = "EMPLOYEE"
+ },
+ new
+ {
+ Id = "cbc43a8e-f7bb-4445-baaf-1add431ffbbf",
+ Name = "Administrator",
+ NormalizedName = "ADMINISTRATOR"
+ });
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ClaimValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RoleId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ClaimValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ProviderKey")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ProviderDisplayName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("RoleId")
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles", (string)null);
+
+ b.HasData(
+ new
+ {
+ UserId = "8e445865-a24d-4543-a6c6-9443d048cdb9",
+ RoleId = "cbc43a8e-f7bb-4445-baaf-1add431ffbbf"
+ },
+ new
+ {
+ UserId = "9e224968-33e4-4652-b7b7-8574d048cdb9",
+ RoleId = "cac43a6e-f7bb-4448-baaf-1add431ccbbf"
+ });
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("LoginProvider")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("HR.LeaveManagement.Identity.Models.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("HR.LeaveManagement.Identity.Models.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("HR.LeaveManagement.Identity.Models.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.HasOne("HR.LeaveManagement.Identity.Models.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/HR.LeaveManagement.Identity/Migrations/20230506212044_FreshMigration.cs b/HR.LeaveManagement.Identity/Migrations/20230506212044_FreshMigration.cs
new file mode 100644
index 0000000..7556a54
--- /dev/null
+++ b/HR.LeaveManagement.Identity/Migrations/20230506212044_FreshMigration.cs
@@ -0,0 +1,255 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
+
+namespace HR.LeaveManagement.Identity.Migrations
+{
+ ///
+ public partial class FreshMigration : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "AspNetRoles",
+ columns: table => new
+ {
+ Id = table.Column(type: "nvarchar(450)", nullable: false),
+ Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
+ NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
+ ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetRoles", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUsers",
+ columns: table => new
+ {
+ Id = table.Column(type: "nvarchar(450)", nullable: false),
+ FirstName = table.Column(type: "nvarchar(max)", nullable: false),
+ LastName = table.Column(type: "nvarchar(max)", nullable: false),
+ UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
+ NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
+ Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
+ NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
+ EmailConfirmed = table.Column(type: "bit", nullable: false),
+ PasswordHash = table.Column(type: "nvarchar(max)", nullable: true),
+ SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true),
+ ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true),
+ PhoneNumber = table.Column(type: "nvarchar(max)", nullable: true),
+ PhoneNumberConfirmed = table.Column(type: "bit", nullable: false),
+ TwoFactorEnabled = table.Column(type: "bit", nullable: false),
+ LockoutEnd = table.Column(type: "datetimeoffset", nullable: true),
+ LockoutEnabled = table.Column(type: "bit", nullable: false),
+ AccessFailedCount = table.Column(type: "int", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUsers", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetRoleClaims",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ RoleId = table.Column(type: "nvarchar(450)", nullable: false),
+ ClaimType = table.Column(type: "nvarchar(max)", nullable: true),
+ ClaimValue = table.Column(type: "nvarchar(max)", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
+ table.ForeignKey(
+ name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
+ column: x => x.RoleId,
+ principalTable: "AspNetRoles",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserClaims",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ UserId = table.Column(type: "nvarchar(450)", nullable: false),
+ ClaimType = table.Column(type: "nvarchar(max)", nullable: true),
+ ClaimValue = table.Column(type: "nvarchar(max)", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
+ table.ForeignKey(
+ name: "FK_AspNetUserClaims_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserLogins",
+ columns: table => new
+ {
+ LoginProvider = table.Column(type: "nvarchar(450)", nullable: false),
+ ProviderKey = table.Column(type: "nvarchar(450)", nullable: false),
+ ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true),
+ UserId = table.Column(type: "nvarchar(450)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
+ table.ForeignKey(
+ name: "FK_AspNetUserLogins_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserRoles",
+ columns: table => new
+ {
+ UserId = table.Column(type: "nvarchar(450)", nullable: false),
+ RoleId = table.Column(type: "nvarchar(450)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
+ table.ForeignKey(
+ name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
+ column: x => x.RoleId,
+ principalTable: "AspNetRoles",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_AspNetUserRoles_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserTokens",
+ columns: table => new
+ {
+ UserId = table.Column(type: "nvarchar(450)", nullable: false),
+ LoginProvider = table.Column(type: "nvarchar(450)", nullable: false),
+ Name = table.Column(type: "nvarchar(450)", nullable: false),
+ Value = table.Column(type: "nvarchar(max)", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
+ table.ForeignKey(
+ name: "FK_AspNetUserTokens_AspNetUsers_UserId",
+ column: x => x.UserId,
+ principalTable: "AspNetUsers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.InsertData(
+ table: "AspNetRoles",
+ columns: new[] { "Id", "ConcurrencyStamp", "Name", "NormalizedName" },
+ values: new object[,]
+ {
+ { "cac43a6e-f7bb-4448-baaf-1add431ccbbf", null, "Employee", "EMPLOYEE" },
+ { "cbc43a8e-f7bb-4445-baaf-1add431ffbbf", null, "Administrator", "ADMINISTRATOR" }
+ });
+
+ migrationBuilder.InsertData(
+ table: "AspNetUsers",
+ columns: new[] { "Id", "AccessFailedCount", "ConcurrencyStamp", "Email", "EmailConfirmed", "FirstName", "LastName", "LockoutEnabled", "LockoutEnd", "NormalizedEmail", "NormalizedUserName", "PasswordHash", "PhoneNumber", "PhoneNumberConfirmed", "SecurityStamp", "TwoFactorEnabled", "UserName" },
+ values: new object[,]
+ {
+ { "8e445865-a24d-4543-a6c6-9443d048cdb9", 0, "a2570d94-af87-4332-8260-e2f319be6161", "admin@localhost.com", true, "System", "Admin", false, null, "ADMIN@LOCALHOST.COM", "ADMIN@LOCALHOST.COM", "AQAAAAIAAYagAAAAEChVlq6vGrjrmWbU3Ut9HAfRfCywAkTDyqPT86JiI7EIrw1U0w9/QwkSBOzbHdsheg==", null, false, "9ad661f8-99c1-4411-a244-ab6b00c08e17", false, "admin@localhost.com" },
+ { "9e224968-33e4-4652-b7b7-8574d048cdb9", 0, "1eed0d78-0687-4f5e-888a-5adbee444629", "user@localhost.com", true, "System", "User", false, null, "USER@LOCALHOST.COM", "USER@LOCALHOST.COM", "AQAAAAIAAYagAAAAEL+FDtu/R9TJijETo1GohRaWxlcTBz6+E7KVAH3ITJjEdzbmjMziyxxtlodn56NDXA==", null, false, "0c8d038a-9388-48ac-8aca-ff749e09e078", false, "user@localhost.com" }
+ });
+
+ migrationBuilder.InsertData(
+ table: "AspNetUserRoles",
+ columns: new[] { "RoleId", "UserId" },
+ values: new object[,]
+ {
+ { "cbc43a8e-f7bb-4445-baaf-1add431ffbbf", "8e445865-a24d-4543-a6c6-9443d048cdb9" },
+ { "cac43a6e-f7bb-4448-baaf-1add431ccbbf", "9e224968-33e4-4652-b7b7-8574d048cdb9" }
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetRoleClaims_RoleId",
+ table: "AspNetRoleClaims",
+ column: "RoleId");
+
+ migrationBuilder.CreateIndex(
+ name: "RoleNameIndex",
+ table: "AspNetRoles",
+ column: "NormalizedName",
+ unique: true,
+ filter: "[NormalizedName] IS NOT NULL");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUserClaims_UserId",
+ table: "AspNetUserClaims",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUserLogins_UserId",
+ table: "AspNetUserLogins",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetUserRoles_RoleId",
+ table: "AspNetUserRoles",
+ column: "RoleId");
+
+ migrationBuilder.CreateIndex(
+ name: "EmailIndex",
+ table: "AspNetUsers",
+ column: "NormalizedEmail");
+
+ migrationBuilder.CreateIndex(
+ name: "UserNameIndex",
+ table: "AspNetUsers",
+ column: "NormalizedUserName",
+ unique: true,
+ filter: "[NormalizedUserName] IS NOT NULL");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "AspNetRoleClaims");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserClaims");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserLogins");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserRoles");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserTokens");
+
+ migrationBuilder.DropTable(
+ name: "AspNetRoles");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUsers");
+ }
+ }
+}
diff --git a/HR.LeaveManagement.Identity/Migrations/HrLeaveManagementIdentityDbContextModelSnapshot.cs b/HR.LeaveManagement.Identity/Migrations/HrLeaveManagementIdentityDbContextModelSnapshot.cs
new file mode 100644
index 0000000..7fb8db4
--- /dev/null
+++ b/HR.LeaveManagement.Identity/Migrations/HrLeaveManagementIdentityDbContextModelSnapshot.cs
@@ -0,0 +1,348 @@
+//
+using System;
+using HR.LeaveManagement.Identity.DbContext;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace HR.LeaveManagement.Identity.Migrations
+{
+ [DbContext(typeof(HrLeaveManagementIdentityDbContext))]
+ partial class HrLeaveManagementIdentityDbContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.5")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("HR.LeaveManagement.Identity.Models.ApplicationUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("AccessFailedCount")
+ .HasColumnType("int");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("EmailConfirmed")
+ .HasColumnType("bit");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LockoutEnabled")
+ .HasColumnType("bit");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumber")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PhoneNumberConfirmed")
+ .HasColumnType("bit");
+
+ b.Property("SecurityStamp")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("TwoFactorEnabled")
+ .HasColumnType("bit");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex")
+ .HasFilter("[NormalizedUserName] IS NOT NULL");
+
+ b.ToTable("AspNetUsers", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = "8e445865-a24d-4543-a6c6-9443d048cdb9",
+ AccessFailedCount = 0,
+ ConcurrencyStamp = "a2570d94-af87-4332-8260-e2f319be6161",
+ Email = "admin@localhost.com",
+ EmailConfirmed = true,
+ FirstName = "System",
+ LastName = "Admin",
+ LockoutEnabled = false,
+ NormalizedEmail = "ADMIN@LOCALHOST.COM",
+ NormalizedUserName = "ADMIN@LOCALHOST.COM",
+ PasswordHash = "AQAAAAIAAYagAAAAEChVlq6vGrjrmWbU3Ut9HAfRfCywAkTDyqPT86JiI7EIrw1U0w9/QwkSBOzbHdsheg==",
+ PhoneNumberConfirmed = false,
+ SecurityStamp = "9ad661f8-99c1-4411-a244-ab6b00c08e17",
+ TwoFactorEnabled = false,
+ UserName = "admin@localhost.com"
+ },
+ new
+ {
+ Id = "9e224968-33e4-4652-b7b7-8574d048cdb9",
+ AccessFailedCount = 0,
+ ConcurrencyStamp = "1eed0d78-0687-4f5e-888a-5adbee444629",
+ Email = "user@localhost.com",
+ EmailConfirmed = true,
+ FirstName = "System",
+ LastName = "User",
+ LockoutEnabled = false,
+ NormalizedEmail = "USER@LOCALHOST.COM",
+ NormalizedUserName = "USER@LOCALHOST.COM",
+ PasswordHash = "AQAAAAIAAYagAAAAEL+FDtu/R9TJijETo1GohRaWxlcTBz6+E7KVAH3ITJjEdzbmjMziyxxtlodn56NDXA==",
+ PhoneNumberConfirmed = false,
+ SecurityStamp = "0c8d038a-9388-48ac-8aca-ff749e09e078",
+ TwoFactorEnabled = false,
+ UserName = "user@localhost.com"
+ });
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex")
+ .HasFilter("[NormalizedName] IS NOT NULL");
+
+ b.ToTable("AspNetRoles", (string)null);
+
+ b.HasData(
+ new
+ {
+ Id = "cac43a6e-f7bb-4448-baaf-1add431ccbbf",
+ Name = "Employee",
+ NormalizedName = "EMPLOYEE"
+ },
+ new
+ {
+ Id = "cbc43a8e-f7bb-4445-baaf-1add431ffbbf",
+ Name = "Administrator",
+ NormalizedName = "ADMINISTRATOR"
+ });
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ClaimValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RoleId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("ClaimType")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ClaimValue")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ProviderKey")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("ProviderDisplayName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("RoleId")
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles", (string)null);
+
+ b.HasData(
+ new
+ {
+ UserId = "8e445865-a24d-4543-a6c6-9443d048cdb9",
+ RoleId = "cbc43a8e-f7bb-4445-baaf-1add431ffbbf"
+ },
+ new
+ {
+ UserId = "9e224968-33e4-4652-b7b7-8574d048cdb9",
+ RoleId = "cac43a6e-f7bb-4448-baaf-1add431ccbbf"
+ });
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("LoginProvider")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Name")
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens", (string)null);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("HR.LeaveManagement.Identity.Models.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("HR.LeaveManagement.Identity.Models.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("HR.LeaveManagement.Identity.Models.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.HasOne("HR.LeaveManagement.Identity.Models.ApplicationUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/HR.LeaveManagement.Identity/Models/ApplicationUser.cs b/HR.LeaveManagement.Identity/Models/ApplicationUser.cs
new file mode 100644
index 0000000..4e9fb09
--- /dev/null
+++ b/HR.LeaveManagement.Identity/Models/ApplicationUser.cs
@@ -0,0 +1,8 @@
+using Microsoft.AspNetCore.Identity;
+
+namespace HR.LeaveManagement.Identity.Models;
+public class ApplicationUser : IdentityUser
+{
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+}
\ No newline at end of file
diff --git a/HR.LeaveManagement.Identity/Services/AuthService.cs b/HR.LeaveManagement.Identity/Services/AuthService.cs
new file mode 100644
index 0000000..d06bcd8
--- /dev/null
+++ b/HR.LeaveManagement.Identity/Services/AuthService.cs
@@ -0,0 +1,110 @@
+using System.IdentityModel.Tokens.Jwt;
+using System.Security.Claims;
+using System.Text;
+
+using HR.LeaveManagement.Application.Contracts.Identity;
+using HR.LeaveManagement.Application.Exceptions;
+using HR.LeaveManagement.Application.Models.Identity;
+using HR.LeaveManagement.Identity.Models;
+
+using Microsoft.AspNetCore.Identity;
+using Microsoft.Extensions.Options;
+using Microsoft.IdentityModel.Tokens;
+
+namespace HR.LeaveManagement.Identity.Services;
+public class AuthService : IAuthService
+{
+ private readonly UserManager _userManager;
+ private readonly SignInManager _signInManager;
+ private readonly JwtSettings _jwtSettings;
+
+ public AuthService(UserManager userManager,
+ IOptions jwtSettings,
+ SignInManager signInManager)
+ {
+ _userManager = userManager;
+ _jwtSettings = jwtSettings.Value;
+ _signInManager = signInManager;
+ }
+
+ public async Task Login(AuthRequest request)
+ {
+ var user = await _userManager.FindByEmailAsync(request.Email) ?? throw new NotFoundException($"User with {request.Email} not found.", request.Email);
+
+ var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password, false);
+
+ if (result.Succeeded == false)
+ throw new BadRequestException($"Credentials for '{request.Email} aren't valid'.");
+
+ JwtSecurityToken jwtSecurityToken = await GenerateToken(user);
+
+ var response = new AuthResponse
+ {
+ Id = user.Id,
+ Token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken),
+ Email = user.Email,
+ UserName = user.UserName
+ };
+
+ return response;
+ }
+
+ public async Task Register(RegistrationRequest request)
+ {
+ var user = new ApplicationUser
+ {
+ Email = request.Email,
+ FirstName = request.FirstName,
+ LastName = request.LastName,
+ UserName = request.UserName,
+ EmailConfirmed = true
+ };
+
+ var result = await _userManager.CreateAsync(user, request.Password);
+
+ if (result.Succeeded)
+ {
+ await _userManager.AddToRoleAsync(user, "Employee");
+ return new RegistrationResponse() { UserId = user.Id };
+ }
+ else
+ {
+ StringBuilder str = new StringBuilder();
+ foreach (var err in result.Errors)
+ str.AppendFormat("•{0}\n", err.Description);
+
+ throw new BadRequestException($"{str}");
+ }
+ }
+
+ private async Task GenerateToken(ApplicationUser user)
+ {
+ var userClaims = await _userManager.GetClaimsAsync(user);
+ var roles = await _userManager.GetRolesAsync(user);
+
+ var roleClaims = roles.Select(q => new Claim(ClaimTypes.Role, q)).ToList();
+
+ var claims = new[]
+ {
+ new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
+ new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
+ new Claim(JwtRegisteredClaimNames.Email, user.Email),
+ new Claim("uid", user.Id)
+ }
+ .Union(userClaims)
+ .Union(roleClaims);
+
+ var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.Key));
+
+ var signingCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256);
+
+ var jwtSecurityToken = new JwtSecurityToken(
+ issuer: _jwtSettings.Issuer,
+ audience: _jwtSettings.Audience,
+ claims: claims,
+ expires: DateTime.Now.AddMinutes(_jwtSettings.DurationInMinutes),
+ signingCredentials: signingCredentials);
+ return jwtSecurityToken;
+ }
+
+}
\ No newline at end of file
diff --git a/HR.LeaveManagement.Identity/Services/UserService.cs b/HR.LeaveManagement.Identity/Services/UserService.cs
new file mode 100644
index 0000000..2301e9c
--- /dev/null
+++ b/HR.LeaveManagement.Identity/Services/UserService.cs
@@ -0,0 +1,47 @@
+using System.Security.Claims;
+
+using HR.LeaveManagement.Application.Contracts.Identity;
+using HR.LeaveManagement.Application.Models.Identity;
+using HR.LeaveManagement.Identity.Models;
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Identity;
+
+namespace HR.LeaveManagement.Identity.Services;
+public class UserService : IUserService
+{
+ private readonly UserManager _userManager;
+ private readonly IHttpContextAccessor _contextAccessor;
+
+ public UserService(UserManager userManager, IHttpContextAccessor contextAccessor)
+ {
+ _userManager = userManager;
+ _contextAccessor = contextAccessor;
+ }
+
+ public string UserId { get => _contextAccessor.HttpContext?.User?.FindFirstValue("uid"); }
+
+ public async Task GetEmployee(string userId)
+ {
+ var employee = await _userManager.FindByIdAsync(userId);
+ return new Employee
+ {
+ Email = employee.Email,
+ Id = employee.Id,
+ Firstname = employee.FirstName,
+ Lastname = employee.LastName
+ };
+ }
+
+ public async Task> GetEmployees()
+ {
+ var employees = await _userManager.GetUsersInRoleAsync("Employee");
+ return employees.Select(q => new Employee
+ {
+ Id = q.Id,
+ Email = q.Email,
+ Firstname = q.FirstName,
+ Lastname = q.LastName
+ }).ToList();
+ }
+}
\ No newline at end of file
diff --git a/HR.LeaveManagement.Persistence/Migrations/20230506211728_MyMigration.Designer.cs b/HR.LeaveManagement.Persistence/Migrations/20230506211728_MyMigration.Designer.cs
new file mode 100644
index 0000000..64c42de
--- /dev/null
+++ b/HR.LeaveManagement.Persistence/Migrations/20230506211728_MyMigration.Designer.cs
@@ -0,0 +1,187 @@
+//
+using System;
+using HR.LeaveManagement.Persistence.DatabaseContext;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace HR.LeaveManagement.Persistence.Migrations
+{
+ [DbContext(typeof(HrDatabaseContext))]
+ [Migration("20230506211728_MyMigration")]
+ partial class MyMigration
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.5")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("HR.LeaveManagement.Domain.LeaveAllocation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DateCreated")
+ .HasColumnType("datetime2");
+
+ b.Property("DateModified")
+ .HasColumnType("datetime2");
+
+ b.Property("EmployeeId")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LeaveTypeId")
+ .HasColumnType("int");
+
+ b.Property("ModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("NumberOfDays")
+ .HasColumnType("int");
+
+ b.Property("Period")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LeaveTypeId");
+
+ b.ToTable("LeaveAllocations");
+ });
+
+ modelBuilder.Entity("HR.LeaveManagement.Domain.LeaveRequest", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Approved")
+ .HasColumnType("bit");
+
+ b.Property("Cancelled")
+ .HasColumnType("bit");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DateCreated")
+ .HasColumnType("datetime2");
+
+ b.Property("DateModified")
+ .HasColumnType("datetime2");
+
+ b.Property("DateRequested")
+ .HasColumnType("datetime2");
+
+ b.Property("EndDate")
+ .HasColumnType("datetime2");
+
+ b.Property("LeaveTypeId")
+ .HasColumnType("int");
+
+ b.Property("ModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RequestComments")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RequestingEmployeeId")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("StartDate")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LeaveTypeId");
+
+ b.ToTable("LeaveRequests");
+ });
+
+ modelBuilder.Entity("HR.LeaveManagement.Domain.LeaveType", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DateCreated")
+ .HasColumnType("datetime2");
+
+ b.Property("DateModified")
+ .HasColumnType("datetime2");
+
+ b.Property("DefaultDays")
+ .HasColumnType("int");
+
+ b.Property("ModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.HasKey("Id");
+
+ b.ToTable("LeaveTypes");
+
+ b.HasData(
+ new
+ {
+ Id = 1,
+ DateCreated = new DateTime(2023, 5, 7, 3, 17, 28, 526, DateTimeKind.Local).AddTicks(2868),
+ DateModified = new DateTime(2023, 5, 7, 3, 17, 28, 526, DateTimeKind.Local).AddTicks(2881),
+ DefaultDays = 10,
+ Name = "Vacation"
+ });
+ });
+
+ modelBuilder.Entity("HR.LeaveManagement.Domain.LeaveAllocation", b =>
+ {
+ b.HasOne("HR.LeaveManagement.Domain.LeaveType", "LeaveType")
+ .WithMany()
+ .HasForeignKey("LeaveTypeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("LeaveType");
+ });
+
+ modelBuilder.Entity("HR.LeaveManagement.Domain.LeaveRequest", b =>
+ {
+ b.HasOne("HR.LeaveManagement.Domain.LeaveType", "LeaveType")
+ .WithMany()
+ .HasForeignKey("LeaveTypeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("LeaveType");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/HR.LeaveManagement.Persistence/Migrations/20230506211728_MyMigration.cs b/HR.LeaveManagement.Persistence/Migrations/20230506211728_MyMigration.cs
new file mode 100644
index 0000000..a2758b8
--- /dev/null
+++ b/HR.LeaveManagement.Persistence/Migrations/20230506211728_MyMigration.cs
@@ -0,0 +1,117 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace HR.LeaveManagement.Persistence.Migrations
+{
+ ///
+ public partial class MyMigration : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "LeaveTypes",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Name = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false),
+ DefaultDays = table.Column(type: "int", nullable: false),
+ DateCreated = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ DateModified = table.Column(type: "datetime2", nullable: true),
+ ModifiedBy = table.Column(type: "nvarchar(max)", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_LeaveTypes", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "LeaveAllocations",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ NumberOfDays = table.Column(type: "int", nullable: false),
+ LeaveTypeId = table.Column(type: "int", nullable: false),
+ Period = table.Column(type: "int", nullable: false),
+ EmployeeId = table.Column(type: "nvarchar(max)", nullable: false),
+ DateCreated = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ DateModified = table.Column(type: "datetime2", nullable: true),
+ ModifiedBy = table.Column(type: "nvarchar(max)", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_LeaveAllocations", x => x.Id);
+ table.ForeignKey(
+ name: "FK_LeaveAllocations_LeaveTypes_LeaveTypeId",
+ column: x => x.LeaveTypeId,
+ principalTable: "LeaveTypes",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "LeaveRequests",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ StartDate = table.Column(type: "datetime2", nullable: false),
+ EndDate = table.Column(type: "datetime2", nullable: false),
+ LeaveTypeId = table.Column(type: "int", nullable: false),
+ DateRequested = table.Column(type: "datetime2", nullable: false),
+ RequestComments = table.Column(type: "nvarchar(max)", nullable: true),
+ Approved = table.Column(type: "bit", nullable: true),
+ Cancelled = table.Column(type: "bit", nullable: false),
+ RequestingEmployeeId = table.Column(type: "nvarchar(max)", nullable: false),
+ DateCreated = table.Column(type: "datetime2", nullable: true),
+ CreatedBy = table.Column(type: "nvarchar(max)", nullable: true),
+ DateModified = table.Column(type: "datetime2", nullable: true),
+ ModifiedBy = table.Column(type: "nvarchar(max)", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_LeaveRequests", x => x.Id);
+ table.ForeignKey(
+ name: "FK_LeaveRequests_LeaveTypes_LeaveTypeId",
+ column: x => x.LeaveTypeId,
+ principalTable: "LeaveTypes",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.InsertData(
+ table: "LeaveTypes",
+ columns: new[] { "Id", "CreatedBy", "DateCreated", "DateModified", "DefaultDays", "ModifiedBy", "Name" },
+ values: new object[] { 1, null, new DateTime(2023, 5, 7, 3, 17, 28, 526, DateTimeKind.Local).AddTicks(2868), new DateTime(2023, 5, 7, 3, 17, 28, 526, DateTimeKind.Local).AddTicks(2881), 10, null, "Vacation" });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_LeaveAllocations_LeaveTypeId",
+ table: "LeaveAllocations",
+ column: "LeaveTypeId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_LeaveRequests_LeaveTypeId",
+ table: "LeaveRequests",
+ column: "LeaveTypeId");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "LeaveAllocations");
+
+ migrationBuilder.DropTable(
+ name: "LeaveRequests");
+
+ migrationBuilder.DropTable(
+ name: "LeaveTypes");
+ }
+ }
+}
diff --git a/HR.LeaveManagement.Persistence/Migrations/HrDatabaseContextModelSnapshot.cs b/HR.LeaveManagement.Persistence/Migrations/HrDatabaseContextModelSnapshot.cs
new file mode 100644
index 0000000..b88122a
--- /dev/null
+++ b/HR.LeaveManagement.Persistence/Migrations/HrDatabaseContextModelSnapshot.cs
@@ -0,0 +1,184 @@
+//
+using System;
+using HR.LeaveManagement.Persistence.DatabaseContext;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace HR.LeaveManagement.Persistence.Migrations
+{
+ [DbContext(typeof(HrDatabaseContext))]
+ partial class HrDatabaseContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.5")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("HR.LeaveManagement.Domain.LeaveAllocation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DateCreated")
+ .HasColumnType("datetime2");
+
+ b.Property("DateModified")
+ .HasColumnType("datetime2");
+
+ b.Property("EmployeeId")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LeaveTypeId")
+ .HasColumnType("int");
+
+ b.Property("ModifiedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("NumberOfDays")
+ .HasColumnType("int");
+
+ b.Property("Period")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LeaveTypeId");
+
+ b.ToTable("LeaveAllocations");
+ });
+
+ modelBuilder.Entity("HR.LeaveManagement.Domain.LeaveRequest", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Approved")
+ .HasColumnType("bit");
+
+ b.Property("Cancelled")
+ .HasColumnType("bit");
+
+ b.Property("CreatedBy")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DateCreated")
+ .HasColumnType("datetime2");
+
+ b.Property("DateModified")
+ .HasColumnType("datetime2");
+
+ b.Property("DateRequested")
+ .HasColumnType("datetime2");
+
+ b.Property("EndDate")
+ .HasColumnType("datetime2");
+
+ b.Property("LeaveTypeId")
+ .HasColumnType("int");
+
+ b.Property