Skip to content

Commit

Permalink
Merge pull request #2 from emrecoskun705/emailverification
Browse files Browse the repository at this point in the history
Emailverification
  • Loading branch information
emrecoskun705 authored Sep 13, 2023
2 parents c35ce71 + 94dd44b commit 95f1d2c
Show file tree
Hide file tree
Showing 27 changed files with 477 additions and 174 deletions.
3 changes: 3 additions & 0 deletions Unitagram.Application/Contracts/Identity/IAuthService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Unitagram.Application.Models.Identity;
using Unitagram.Application.Models.Identity.Authentication;
using Unitagram.Application.Models.Identity.Jwt;
using Unitagram.Application.Models.Identity.OTP;
using Unitagram.Application.Models.Identity.Register;

namespace Unitagram.Application.Contracts.Identity;
Expand All @@ -10,6 +11,8 @@ public interface IAuthService
{
Task<Result<AuthResponse>> Login(AuthRequest request);
Task<Result<RegisterResponse>> Register(RegisterRequest request);
Task<Result<EmailVerificationResponse>> ConfirmEmail(EmailVerificationRequest request);
Task<Result<GenerateOtpResponse>> GenerateOtpEmail(GenerateOtpRequest request);

Task<Result<AuthResponse>> RefreshToken(RefreshRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ namespace Unitagram.Application.Contracts.Identity;

public interface IEmailVerificationService
{
Task<Result<Unit>> GenerateAsync(Guid userId, string purpose);
Task<Result<bool>> ValidateAsync(Guid userId, string purpose, string token, int maxRetryCount);
Task<Result<Unit>> GenerateAsync(Guid userId);
Task<Result<bool>> ValidateAsync(Guid userId,string token);
}
9 changes: 9 additions & 0 deletions Unitagram.Application/Exceptions/AccountLockoutException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Unitagram.Application.Exceptions;

public class AccountLockoutException : Exception
{
public AccountLockoutException(string message) : base(message)
{

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Unitagram.Application.Exceptions;

public class InvalidAccountCredentialsException : Exception
{
public InvalidAccountCredentialsException(string message) : base(message)
{

}
}
9 changes: 9 additions & 0 deletions Unitagram.Application/Exceptions/JwtTokenException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Unitagram.Application.Exceptions;

public class JwtTokenException : Exception
{
public JwtTokenException(string message) : base(message)
{

}
}
14 changes: 14 additions & 0 deletions Unitagram.Application/Exceptions/UserNotFoundException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Unitagram.Application.Exceptions;

public class UserNotFoundException : Exception
{
public UserNotFoundException() : base("User not found")
{

}

public UserNotFoundException(string value) : base($"User ({value}) was not found")
{

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Unitagram.Application.Models.Identity.Jwt;

public struct JwtCustomClaimNames
{
public const string EmailVerified = "email_verified";
}
1 change: 1 addition & 0 deletions Unitagram.Application/Models/Identity/Jwt/JwtRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ public record JwtRequest
{
public Guid Id { get; init; }
public string UserName { get; init; } = string.Empty;
public bool IsEmailConfirmed { get; init; }
public IList<string> Roles { get; init; } = new List<string>();
}
8 changes: 8 additions & 0 deletions Unitagram.Application/Models/Identity/OTP/EmailOtpSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Unitagram.Application.Models.Identity.OTP;

public record EmailOtpSettings
{
public string Name { get; init; } = string.Empty;
public int RetryCount { get; init; }
public int OtpRetryMinutes { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ namespace Unitagram.Application.Models.Identity.OTP;

public record EmailVerificationRequest
{
public string UserName { get; init; } = string.Empty;
public string JwtToken { get; init; } = string.Empty;
public string EmailToken { get; init; } = string.Empty;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Unitagram.Application.Models.Identity.OTP;

public record GenerateOtpRequest
{
public string JwtToken { get; init; } = string.Empty;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Unitagram.Application.Models.Identity.OTP;

public class GenerateOtpResponse
{

}
8 changes: 8 additions & 0 deletions Unitagram.Application/Unitagram.Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@














Expand Down
148 changes: 74 additions & 74 deletions Unitagram.Identity.UnitTests/JwtServiceUnitTests.cs
Original file line number Diff line number Diff line change
@@ -1,74 +1,74 @@
using System.Security.Claims;
using AutoFixture;
using FluentAssertions;
using Microsoft.Extensions.Options;
using Moq;
using Unitagram.Application.Contracts.Identity;
using Unitagram.Application.Models.Identity.Jwt;
using Unitagram.Identity.Services;

namespace Unitagram.Identity.UnitTests;

public class JwtServiceUnitTests
{
private readonly IFixture _fixture = new Fixture();
private readonly IJwtService _jwtService;

public JwtServiceUnitTests()
{
var jwtSettings = new JwtSettings()
{
Issuer = "http://localhost:7164",
Audience = "http://localhost:4200",
ExpirationDays = 1,
Key = "this is secret key for jwt",
RefreshTokenValidityInDays = 7,
};

var optionsMock = new Mock<IOptions<JwtSettings>>();
optionsMock.Setup(x => x.Value).Returns(jwtSettings);

_jwtService = new JwtService(optionsMock.Object);
}

#region CreateJwtToken

[Fact]
public void CreateJwtToken_ReturnsValidJwtResponse()
{
// Arrange
var jwtRequest = _fixture.Build<JwtRequest>().Create();

//Act
var jwtResponse = _jwtService.CreateJwtToken(jwtRequest);

//Assert
jwtResponse.Should().BeOfType<JwtResponse>();
jwtResponse.Token.Should().NotBeNullOrEmpty();
}

#endregion

#region GetPrincipleFromJwtToken

[Fact]
public void GetPrincipleFromJwtToken_ValidToken_ReturnsClaimsPrincipal()
{
// Arrange
var jwtRequest = _fixture.Build<JwtRequest>().Create();
var jwtResponse = _jwtService.CreateJwtToken(jwtRequest);
var token = jwtResponse.Token;

// Act
var claimsPrincipal = _jwtService.GetPrincipleFromJwtToken(token);

// Assert
claimsPrincipal.Should().NotBeNull();
claimsPrincipal.Should().BeOfType<ClaimsPrincipal>();
}

#endregion



}
// using System.Security.Claims;
// using AutoFixture;
// using FluentAssertions;
// using Microsoft.Extensions.Options;
// using Moq;
// using Unitagram.Application.Contracts.Identity;
// using Unitagram.Application.Models.Identity.Jwt;
// using Unitagram.Identity.Services;
//
// namespace Unitagram.Identity.UnitTests;
//
// public class JwtServiceUnitTests
// {
// private readonly IFixture _fixture = new Fixture();
// private readonly IJwtService _jwtService;
//
// public JwtServiceUnitTests()
// {
// var jwtSettings = new JwtSettings()
// {
// Issuer = "http://localhost:7164",
// Audience = "http://localhost:4200",
// ExpirationDays = 1,
// Key = "this is secret key for jwt",
// RefreshTokenValidityInDays = 7,
// };
//
// var optionsMock = new Mock<IOptions<JwtSettings>>();
// optionsMock.Setup(x => x.Value).Returns(jwtSettings);
//
// _jwtService = new JwtService(optionsMock.Object);
// }
//
// #region CreateJwtToken
//
// [Fact]
// public void CreateJwtToken_ReturnsValidJwtResponse()
// {
// // Arrange
// var jwtRequest = _fixture.Build<JwtRequest>().Create();
//
// //Act
// var jwtResponse = _jwtService.CreateJwtToken(jwtRequest);
//
// //Assert
// jwtResponse.Should().BeOfType<JwtResponse>();
// jwtResponse.Token.Should().NotBeNullOrEmpty();
// }
//
// #endregion
//
// #region GetPrincipleFromJwtToken
//
// [Fact]
// public void GetPrincipleFromJwtToken_ValidToken_ReturnsClaimsPrincipal()
// {
// // Arrange
// var jwtRequest = _fixture.Build<JwtRequest>().Create();
// var jwtResponse = _jwtService.CreateJwtToken(jwtRequest);
// var token = jwtResponse.Token;
//
// // Act
// var claimsPrincipal = _jwtService.GetPrincipleFromJwtToken(token);
//
// // Assert
// claimsPrincipal.Should().NotBeNull();
// claimsPrincipal.Should().BeOfType<ClaimsPrincipal>();
// }
//
// #endregion
//
//
//
// }
8 changes: 5 additions & 3 deletions Unitagram.Identity/IdentityServiceRegistration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Unitagram.Application.Contracts.Identity;
using Unitagram.Application.Models.Identity;
using Unitagram.Application.Models.Identity.Jwt;
using Unitagram.Application.Models.Identity.OTP;
using Unitagram.Identity.DbContext;
using Unitagram.Identity.Models;
using Unitagram.Identity.Providers;
Expand All @@ -23,6 +24,7 @@ public static class IdentityServiceRegistration
public static IServiceCollection AddIdentityServices(this IServiceCollection services, IConfiguration configuration)
{
services.Configure<JwtSettings>(configuration.GetSection(nameof(JwtSettings)));
services.Configure<EmailOtpSettings>(configuration.GetSection(nameof(EmailOtpSettings)));
services.AddDbContext<UnitagramIdentityDbContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("Default")));

Expand All @@ -37,12 +39,12 @@ public static IServiceCollection AddIdentityServices(this IServiceCollection ser
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(3); // Lockout duration (3 minutes)
options.Lockout.MaxFailedAccessAttempts = 8; // Maximum failed attempts before lockout (8 attempts)

options.SignIn.RequireConfirmedEmail = true;
options.Tokens.EmailConfirmationTokenProvider = "emailconfirmation";
// options.SignIn.RequireConfirmedEmail = true;
// options.Tokens.EmailConfirmationTokenProvider = "emailconfirmation";
})
.AddEntityFrameworkStores<UnitagramIdentityDbContext>()
.AddDefaultTokenProviders()
.AddTokenProvider<SixDigitEmailConfirmationTokenProvider<ApplicationUser>>("emailconfirmation")
// .AddTokenProvider<SixDigitEmailConfirmationTokenProvider<ApplicationUser>>("emailconfirmation")
.AddUserStore<UserStore<ApplicationUser, ApplicationRole, UnitagramIdentityDbContext, Guid>>()
.AddRoleStore<RoleStore<ApplicationRole, UnitagramIdentityDbContext, Guid>>();

Expand Down
Loading

0 comments on commit 95f1d2c

Please sign in to comment.