diff --git a/src/Core/API/API.Specs/Features/Registration.feature b/src/Core/API/API.Specs/Features/Registration.feature
index 7625078..5e09b31 100644
--- a/src/Core/API/API.Specs/Features/Registration.feature
+++ b/src/Core/API/API.Specs/Features/Registration.feature
@@ -1,69 +1,75 @@
Feature: User Registration
- As a new user
- I want to register an account
- So that I can log in and access authenticated routes
- @Ignore
- Scenario: Successful registration with valid details
- Given the API is running
- When I submit a registration request with values:
- | Username | FirstName | LastName | Email | DateOfBirth | Password |
- | newuser | New | User | newuser@example.com | 1990-01-01 | Password1! |
- Then the response has HTTP status 201
- And the response JSON should have "message" equal "User registered successfully."
- And the response JSON should have an access token
- @Ignore
- Scenario: Registration fails with existing username
- Given the API is running
- And I have an existing account with username "existinguser"
- When I submit a registration request with values:
- | Username | FirstName | LastName | Email | DateOfBirth | Password |
- | existinguser | Existing | User | existing@example.com | 1990-01-01 | Password1! |
- Then the response has HTTP status 409
- And the response JSON should have "message" equal "Username already exists."
- @Ignore
- Scenario: Registration fails with existing email
- Given the API is running
- And I have an existing account with email "existing@example.com"
- When I submit a registration request with values:
- | Username | FirstName | LastName | Email | DateOfBirth | Password |
- | newuser | New | User | existing@example.com | 1990-01-01 | Password1! |
- Then the response has HTTP status 409
- And the response JSON should have "message" equal "Email already in use."
- @Ignore
- Scenario: Registration fails with missing required fields
- Given the API is running
- When I submit a registration request with values:
- | Username | FirstName | LastName | Email | DateOfBirth | Password |
- | | New | User | | | Password1! |
- Then the response has HTTP status 400
- And the response JSON should have "message" equal "Username is required."
- @Ignore
- Scenario: Registration fails with invalid email format
- Given the API is running
- When I submit a registration request with values:
- | Username | FirstName | LastName | Email | DateOfBirth | Password |
- | newuser | New | User | invalidemail | 1990-01-01 | Password1! |
- Then the response has HTTP status 400
- And the response JSON should have "message" equal "Invalid email format."
- @Ignore
- Scenario: Registration fails with weak password
- Given the API is running
- When I submit a registration request with values:
- | Username | FirstName | LastName | Email | DateOfBirth | Password |
- | newuser | New | User | newuser@example.com | 1990-01-01 | weakpass |
- Then the response has HTTP status 400
- And the response JSON should have "message" equal "Password does not meet complexity requirements."
- @Ignore
- Scenario: Cannot register a user younger than 19 years of age (regulatory requirement)
- Given the API is running
- When I submit a registration request with values:
- | Username | FirstName | LastName | Email | DateOfBirth | Password |
- | younguser | Young | User | younguser@example.com | | Password1! |
- Then the response has HTTP status 400
- And the response JSON should have "message" equal "You must be at least 19 years old to register."
- @Ignore
- Scenario: Registration endpoint only accepts POST requests
- Given the API is running
- When I submit a registration request using a GET request
- Then the response has HTTP status 404
- And the response JSON should have "message" equal "Not Found."
+As a new user
+I want to register an account
+So that I can log in and access authenticated routes
+
+ Scenario: Successful registration with valid details
+ Given the API is running
+ When I submit a registration request with values:
+ | Username | FirstName | LastName | Email | DateOfBirth | Password |
+ | newuser | New | User | newuser@example.com | 1990-01-01 | Password1! |
+ Then the response has HTTP status 201
+ And the response JSON should have "message" equal "User registered successfully."
+ And the response JSON should have an access token
+
+ @Ignore
+ Scenario: Registration fails with existing username
+ Given the API is running
+ And I have an existing account with username "existinguser"
+ When I submit a registration request with values:
+ | Username | FirstName | LastName | Email | DateOfBirth | Password |
+ | existinguser | Existing | User | existing@example.com | 1990-01-01 | Password1! |
+ Then the response has HTTP status 409
+ And the response JSON should have "message" equal "Username already exists."
+
+ @Ignore
+ Scenario: Registration fails with existing email
+ Given the API is running
+ And I have an existing account with email "existing@example.com"
+ When I submit a registration request with values:
+ | Username | FirstName | LastName | Email | DateOfBirth | Password |
+ | newuser | New | User | existing@example.com | 1990-01-01 | Password1! |
+ Then the response has HTTP status 409
+ And the response JSON should have "message" equal "Email already in use."
+
+ @Ignore
+ Scenario: Registration fails with missing required fields
+ Given the API is running
+ When I submit a registration request with values:
+ | Username | FirstName | LastName | Email | DateOfBirth | Password |
+ | | New | User | | | Password1! |
+ Then the response has HTTP status 400
+ And the response JSON should have "message" equal "Username is required."
+
+ @Ignore
+ Scenario: Registration fails with invalid email format
+ Given the API is running
+ When I submit a registration request with values:
+ | Username | FirstName | LastName | Email | DateOfBirth | Password |
+ | newuser | New | User | invalidemail | 1990-01-01 | Password1! |
+ Then the response has HTTP status 400
+ And the response JSON should have "message" equal "Invalid email format."
+
+ @Ignore
+ Scenario: Registration fails with weak password
+ Given the API is running
+ When I submit a registration request with values:
+ | Username | FirstName | LastName | Email | DateOfBirth | Password |
+ | newuser | New | User | newuser@example.com | 1990-01-01 | weakpass |
+ Then the response has HTTP status 400
+ And the response JSON should have "message" equal "Password does not meet complexity requirements."
+
+ @Ignore
+ Scenario: Cannot register a user younger than 19 years of age (regulatory requirement)
+ Given the API is running
+ When I submit a registration request with values:
+ | Username | FirstName | LastName | Email | DateOfBirth | Password |
+ | younguser | Young | User | younguser@example.com | | Password1! |
+ Then the response has HTTP status 400
+ And the response JSON should have "message" equal "You must be at least 19 years old to register."
+
+ Scenario: Registration endpoint only accepts POST requests
+ Given the API is running
+ When I submit a registration request using a GET request
+ Then the response has HTTP status 404
+ And the response JSON should have "message" equal "Not Found."
\ No newline at end of file
diff --git a/src/Core/API/API.Specs/Steps/AuthSteps.cs b/src/Core/API/API.Specs/Steps/AuthSteps.cs
index 92ae4c7..bc745f4 100644
--- a/src/Core/API/API.Specs/Steps/AuthSteps.cs
+++ b/src/Core/API/API.Specs/Steps/AuthSteps.cs
@@ -157,4 +157,64 @@ public class AuthSteps(ScenarioContext scenario)
scenario[ResponseKey] = response;
scenario[ResponseBodyKey] = responseBody;
}
+
+ [When("I submit a registration request with values:")]
+ public async Task WhenISubmitARegistrationRequestWithValues(Table table)
+ {
+ var client = GetClient();
+ var row = table.Rows[0];
+
+ var registrationData = new
+ {
+ username = row.TryGetValue("Username", out var value) ? value : null,
+ firstName = row.TryGetValue("FirstName", out var value1) ? value1 : null,
+ lastName = row.TryGetValue("LastName", out var value2) ? value2 : null,
+ email = row.TryGetValue("Email", out var value3) ? value3 : null,
+ dateOfBirth = row.ContainsKey("DateOfBirth") && !string.IsNullOrEmpty(row["DateOfBirth"])
+ ? row["DateOfBirth"]
+ : null,
+ password = row.ContainsKey("Password") ? row["Password"] : null
+ };
+
+ var body = JsonSerializer.Serialize(registrationData);
+
+ var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/api/auth/register")
+ {
+ Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json")
+ };
+
+ var response = await client.SendAsync(requestMessage);
+ var responseBody = await response.Content.ReadAsStringAsync();
+
+ scenario[ResponseKey] = response;
+ scenario[ResponseBodyKey] = responseBody;
+ }
+
+ [Given("I have an existing account with username {string}")]
+ public void GivenIHaveAnExistingAccountWithUsername(string username)
+ {
+
+ }
+
+ [Given("I have an existing account with email {string}")]
+ public void GivenIHaveAnExistingAccountWithEmail(string email)
+ {
+
+ }
+
+ [When("I submit a registration request using a GET request")]
+ public async Task WhenISubmitARegistrationRequestUsingAGetRequest()
+ {
+ var client = GetClient();
+ var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/auth/register")
+ {
+ Content = new StringContent("{}", System.Text.Encoding.UTF8, "application/json")
+ };
+
+ var response = await client.SendAsync(requestMessage);
+ var responseBody = await response.Content.ReadAsStringAsync();
+
+ scenario[ResponseKey] = response;
+ scenario[ResponseBodyKey] = responseBody;
+ }
}
\ No newline at end of file
diff --git a/src/Core/Repository/Repository.Core/Repositories/Auth/AuthRepository.cs b/src/Core/Repository/Repository.Core/Repositories/Auth/AuthRepository.cs
index de2964a..e3a8495 100644
--- a/src/Core/Repository/Repository.Core/Repositories/Auth/AuthRepository.cs
+++ b/src/Core/Repository/Repository.Core/Repositories/Auth/AuthRepository.cs
@@ -22,10 +22,10 @@ namespace Repository.Core.Repositories.Auth
{
await using var connection = await CreateConnection();
await using var command = connection.CreateCommand();
+
command.CommandText = "USP_RegisterUser";
command.CommandType = CommandType.StoredProcedure;
- // Input parameters
AddParameter(command, "@Username", username);
AddParameter(command, "@FirstName", firstName);
AddParameter(command, "@LastName", lastName);
@@ -33,11 +33,9 @@ namespace Repository.Core.Repositories.Auth
AddParameter(command, "@DateOfBirth", dateOfBirth);
AddParameter(command, "@Hash", passwordHash);
- // Execute and retrieve the generated UserAccountId from result set
var result = await command.ExecuteScalarAsync();
var userAccountId = result != null ? (Guid)result : Guid.Empty;
- // Return the newly created user account
return new Entities.UserAccount
{
UserAccountId = userAccountId,
@@ -104,12 +102,6 @@ namespace Repository.Core.Repositories.Auth
await command.ExecuteNonQueryAsync();
}
-
- public async Task InvalidateCredentialsByUserAccountIdAsync(Guid userAccountId)
- {
- throw new NotImplementedException("InvalidateCredentialsByUserAccountIdAsync");
- }
-
///
/// Maps a data reader row to a UserAccount entity.
///
@@ -172,4 +164,4 @@ namespace Repository.Core.Repositories.Auth
command.Parameters.Add(p);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Core/Repository/Repository.Core/Repositories/Auth/IAuthRepository.cs b/src/Core/Repository/Repository.Core/Repositories/Auth/IAuthRepository.cs
index 36a1242..df945a1 100644
--- a/src/Core/Repository/Repository.Core/Repositories/Auth/IAuthRepository.cs
+++ b/src/Core/Repository/Repository.Core/Repositories/Auth/IAuthRepository.cs
@@ -55,12 +55,5 @@ namespace Repository.Core.Repositories.Auth
/// ID of the user account
/// New hashed password
Task RotateCredentialAsync(Guid userAccountId, string newPasswordHash);
-
- ///
- /// Invalidates all credentials for a user account (e.g., for logout or security purposes).
- /// Uses stored procedure: USP_InvalidateUserCredential
- ///
- /// ID of the user account
- Task InvalidateCredentialsByUserAccountIdAsync(Guid userAccountId);
}
}
diff --git a/src/Core/Repository/Repository.Tests/Auth/AuthRepository.test.cs b/src/Core/Repository/Repository.Tests/Auth/AuthRepository.test.cs
index e021947..91b6d4a 100644
--- a/src/Core/Repository/Repository.Tests/Auth/AuthRepository.test.cs
+++ b/src/Core/Repository/Repository.Tests/Auth/AuthRepository.test.cs
@@ -8,225 +8,212 @@ namespace Repository.Tests.Auth;
public class AuthRepositoryTest
{
- private static AuthRepository CreateRepo(MockDbConnection conn)
- => new(new TestConnectionFactory(conn));
+ private static AuthRepository CreateRepo(MockDbConnection conn)
+ => new(new TestConnectionFactory(conn));
- [Fact]
- public async Task RegisterUserAsync_CreatesUserWithCredential_ReturnsUserAccount()
- {
- var expectedUserId = Guid.NewGuid();
- var conn = new MockDbConnection();
+ [Fact]
+ public async Task RegisterUserAsync_CreatesUserWithCredential_ReturnsUserAccount()
+ {
+ var expectedUserId = Guid.NewGuid();
+ var conn = new MockDbConnection();
- conn.Mocks
- .When(cmd => cmd.CommandText == "USP_RegisterUser")
- .ReturnsTable(MockTable.WithColumns(("UserAccountId", typeof(Guid)))
- .AddRow(expectedUserId));
+ conn.Mocks
+ .When(cmd => cmd.CommandText == "USP_RegisterUser")
+ .ReturnsTable(MockTable.WithColumns(("UserAccountId", typeof(Guid)))
+ .AddRow(expectedUserId));
- var repo = CreateRepo(conn);
- var result = await repo.RegisterUserAsync(
- username: "testuser",
- firstName: "Test",
- lastName: "User",
- email: "test@example.com",
- dateOfBirth: new DateTime(1990, 1, 1),
- passwordHash: "hashedpassword123"
- );
+ var repo = CreateRepo(conn);
+ var result = await repo.RegisterUserAsync(
+ username: "testuser",
+ firstName: "Test",
+ lastName: "User",
+ email: "test@example.com",
+ dateOfBirth: new DateTime(1990, 1, 1),
+ passwordHash: "hashedpassword123"
+ );
- result.Should().NotBeNull();
- result.UserAccountId.Should().Be(expectedUserId);
- result.Username.Should().Be("testuser");
- result.FirstName.Should().Be("Test");
- result.LastName.Should().Be("User");
- result.Email.Should().Be("test@example.com");
- result.DateOfBirth.Should().Be(new DateTime(1990, 1, 1));
- }
+ result.Should().NotBeNull();
+ result.UserAccountId.Should().Be(expectedUserId);
+ result.Username.Should().Be("testuser");
+ result.FirstName.Should().Be("Test");
+ result.LastName.Should().Be("User");
+ result.Email.Should().Be("test@example.com");
+ result.DateOfBirth.Should().Be(new DateTime(1990, 1, 1));
+ }
- [Fact]
- public async Task GetUserByEmailAsync_ReturnsUser_WhenExists()
- {
- var userId = Guid.NewGuid();
- var conn = new MockDbConnection();
+ [Fact]
+ public async Task GetUserByEmailAsync_ReturnsUser_WhenExists()
+ {
+ var userId = Guid.NewGuid();
+ var conn = new MockDbConnection();
- conn.Mocks
- .When(cmd => cmd.CommandText == "usp_GetUserAccountByEmail")
- .ReturnsTable(MockTable.WithColumns(
- ("UserAccountId", typeof(Guid)),
- ("Username", typeof(string)),
- ("FirstName", typeof(string)),
- ("LastName", typeof(string)),
- ("Email", typeof(string)),
- ("CreatedAt", typeof(DateTime)),
- ("UpdatedAt", typeof(DateTime?)),
- ("DateOfBirth", typeof(DateTime)),
- ("Timer", typeof(byte[]))
- ).AddRow(
- userId,
- "emailuser",
- "Email",
- "User",
- "emailuser@example.com",
- DateTime.UtcNow,
- null,
- new DateTime(1990, 5, 15),
- null
- ));
+ conn.Mocks
+ .When(cmd => cmd.CommandText == "usp_GetUserAccountByEmail")
+ .ReturnsTable(MockTable.WithColumns(
+ ("UserAccountId", typeof(Guid)),
+ ("Username", typeof(string)),
+ ("FirstName", typeof(string)),
+ ("LastName", typeof(string)),
+ ("Email", typeof(string)),
+ ("CreatedAt", typeof(DateTime)),
+ ("UpdatedAt", typeof(DateTime?)),
+ ("DateOfBirth", typeof(DateTime)),
+ ("Timer", typeof(byte[]))
+ ).AddRow(
+ userId,
+ "emailuser",
+ "Email",
+ "User",
+ "emailuser@example.com",
+ DateTime.UtcNow,
+ null,
+ new DateTime(1990, 5, 15),
+ null
+ ));
- var repo = CreateRepo(conn);
- var result = await repo.GetUserByEmailAsync("emailuser@example.com");
+ var repo = CreateRepo(conn);
+ var result = await repo.GetUserByEmailAsync("emailuser@example.com");
- result.Should().NotBeNull();
- result!.UserAccountId.Should().Be(userId);
- result.Username.Should().Be("emailuser");
- result.Email.Should().Be("emailuser@example.com");
- result.FirstName.Should().Be("Email");
- result.LastName.Should().Be("User");
- }
+ result.Should().NotBeNull();
+ result!.UserAccountId.Should().Be(userId);
+ result.Username.Should().Be("emailuser");
+ result.Email.Should().Be("emailuser@example.com");
+ result.FirstName.Should().Be("Email");
+ result.LastName.Should().Be("User");
+ }
- [Fact]
- public async Task GetUserByEmailAsync_ReturnsNull_WhenNotExists()
- {
- var conn = new MockDbConnection();
+ [Fact]
+ public async Task GetUserByEmailAsync_ReturnsNull_WhenNotExists()
+ {
+ var conn = new MockDbConnection();
- conn.Mocks
- .When(cmd => cmd.CommandText == "usp_GetUserAccountByEmail")
- .ReturnsTable(MockTable.Empty());
+ conn.Mocks
+ .When(cmd => cmd.CommandText == "usp_GetUserAccountByEmail")
+ .ReturnsTable(MockTable.Empty());
- var repo = CreateRepo(conn);
- var result = await repo.GetUserByEmailAsync("nonexistent@example.com");
+ var repo = CreateRepo(conn);
+ var result = await repo.GetUserByEmailAsync("nonexistent@example.com");
- result.Should().BeNull();
- }
+ result.Should().BeNull();
+ }
- [Fact]
- public async Task GetUserByUsernameAsync_ReturnsUser_WhenExists()
- {
- var userId = Guid.NewGuid();
- var conn = new MockDbConnection();
+ [Fact]
+ public async Task GetUserByUsernameAsync_ReturnsUser_WhenExists()
+ {
+ var userId = Guid.NewGuid();
+ var conn = new MockDbConnection();
- conn.Mocks
- .When(cmd => cmd.CommandText == "usp_GetUserAccountByUsername")
- .ReturnsTable(MockTable.WithColumns(
- ("UserAccountId", typeof(Guid)),
- ("Username", typeof(string)),
- ("FirstName", typeof(string)),
- ("LastName", typeof(string)),
- ("Email", typeof(string)),
- ("CreatedAt", typeof(DateTime)),
- ("UpdatedAt", typeof(DateTime?)),
- ("DateOfBirth", typeof(DateTime)),
- ("Timer", typeof(byte[]))
- ).AddRow(
- userId,
- "usernameuser",
- "Username",
- "User",
- "username@example.com",
- DateTime.UtcNow,
- null,
- new DateTime(1985, 8, 20),
- null
- ));
+ conn.Mocks
+ .When(cmd => cmd.CommandText == "usp_GetUserAccountByUsername")
+ .ReturnsTable(MockTable.WithColumns(
+ ("UserAccountId", typeof(Guid)),
+ ("Username", typeof(string)),
+ ("FirstName", typeof(string)),
+ ("LastName", typeof(string)),
+ ("Email", typeof(string)),
+ ("CreatedAt", typeof(DateTime)),
+ ("UpdatedAt", typeof(DateTime?)),
+ ("DateOfBirth", typeof(DateTime)),
+ ("Timer", typeof(byte[]))
+ ).AddRow(
+ userId,
+ "usernameuser",
+ "Username",
+ "User",
+ "username@example.com",
+ DateTime.UtcNow,
+ null,
+ new DateTime(1985, 8, 20),
+ null
+ ));
- var repo = CreateRepo(conn);
- var result = await repo.GetUserByUsernameAsync("usernameuser");
+ var repo = CreateRepo(conn);
+ var result = await repo.GetUserByUsernameAsync("usernameuser");
- result.Should().NotBeNull();
- result!.UserAccountId.Should().Be(userId);
- result.Username.Should().Be("usernameuser");
- result.Email.Should().Be("username@example.com");
- }
+ result.Should().NotBeNull();
+ result!.UserAccountId.Should().Be(userId);
+ result.Username.Should().Be("usernameuser");
+ result.Email.Should().Be("username@example.com");
+ }
- [Fact]
- public async Task GetUserByUsernameAsync_ReturnsNull_WhenNotExists()
- {
- var conn = new MockDbConnection();
+ [Fact]
+ public async Task GetUserByUsernameAsync_ReturnsNull_WhenNotExists()
+ {
+ var conn = new MockDbConnection();
- conn.Mocks
- .When(cmd => cmd.CommandText == "usp_GetUserAccountByUsername")
- .ReturnsTable(MockTable.Empty());
+ conn.Mocks
+ .When(cmd => cmd.CommandText == "usp_GetUserAccountByUsername")
+ .ReturnsTable(MockTable.Empty());
- var repo = CreateRepo(conn);
- var result = await repo.GetUserByUsernameAsync("nonexistent");
+ var repo = CreateRepo(conn);
+ var result = await repo.GetUserByUsernameAsync("nonexistent");
- result.Should().BeNull();
- }
+ result.Should().BeNull();
+ }
- [Fact]
- public async Task GetActiveCredentialByUserAccountIdAsync_ReturnsCredential_WhenExists()
- {
- var userId = Guid.NewGuid();
- var credentialId = Guid.NewGuid();
- var conn = new MockDbConnection();
+ [Fact]
+ public async Task GetActiveCredentialByUserAccountIdAsync_ReturnsCredential_WhenExists()
+ {
+ var userId = Guid.NewGuid();
+ var credentialId = Guid.NewGuid();
+ var conn = new MockDbConnection();
- conn.Mocks
- .When(cmd => cmd.CommandText == "USP_GetActiveUserCredentialByUserAccountId")
- .ReturnsTable(MockTable.WithColumns(
- ("UserCredentialId", typeof(Guid)),
- ("UserAccountId", typeof(Guid)),
- ("Hash", typeof(string)),
- ("CreatedAt", typeof(DateTime)),
- ("Timer", typeof(byte[]))
- ).AddRow(
- credentialId,
- userId,
- "hashed_password_value",
- DateTime.UtcNow,
- null
- ));
+ conn.Mocks
+ .When(cmd => cmd.CommandText == "USP_GetActiveUserCredentialByUserAccountId")
+ .ReturnsTable(MockTable.WithColumns(
+ ("UserCredentialId", typeof(Guid)),
+ ("UserAccountId", typeof(Guid)),
+ ("Hash", typeof(string)),
+ ("CreatedAt", typeof(DateTime)),
+ ("Timer", typeof(byte[]))
+ ).AddRow(
+ credentialId,
+ userId,
+ "hashed_password_value",
+ DateTime.UtcNow,
+ null
+ ));
- var repo = CreateRepo(conn);
- var result = await repo.GetActiveCredentialByUserAccountIdAsync(userId);
+ var repo = CreateRepo(conn);
+ var result = await repo.GetActiveCredentialByUserAccountIdAsync(userId);
- result.Should().NotBeNull();
- result!.UserCredentialId.Should().Be(credentialId);
- result.UserAccountId.Should().Be(userId);
- result.Hash.Should().Be("hashed_password_value");
- }
+ result.Should().NotBeNull();
+ result!.UserCredentialId.Should().Be(credentialId);
+ result.UserAccountId.Should().Be(userId);
+ result.Hash.Should().Be("hashed_password_value");
+ }
- [Fact]
- public async Task GetActiveCredentialByUserAccountIdAsync_ReturnsNull_WhenNotExists()
- {
- var userId = Guid.NewGuid();
- var conn = new MockDbConnection();
+ [Fact]
+ public async Task GetActiveCredentialByUserAccountIdAsync_ReturnsNull_WhenNotExists()
+ {
+ var userId = Guid.NewGuid();
+ var conn = new MockDbConnection();
- conn.Mocks
- .When(cmd => cmd.CommandText == "USP_GetActiveUserCredentialByUserAccountId")
- .ReturnsTable(MockTable.Empty());
+ conn.Mocks
+ .When(cmd => cmd.CommandText == "USP_GetActiveUserCredentialByUserAccountId")
+ .ReturnsTable(MockTable.Empty());
- var repo = CreateRepo(conn);
- var result = await repo.GetActiveCredentialByUserAccountIdAsync(userId);
+ var repo = CreateRepo(conn);
+ var result = await repo.GetActiveCredentialByUserAccountIdAsync(userId);
- result.Should().BeNull();
- }
+ result.Should().BeNull();
+ }
- [Fact]
- public async Task RotateCredentialAsync_ExecutesSuccessfully()
- {
- var userId = Guid.NewGuid();
- var newPasswordHash = "new_hashed_password";
- var conn = new MockDbConnection();
+ [Fact]
+ public async Task RotateCredentialAsync_ExecutesSuccessfully()
+ {
+ var userId = Guid.NewGuid();
+ var newPasswordHash = "new_hashed_password";
+ var conn = new MockDbConnection();
- conn.Mocks
- .When(cmd => cmd.CommandText == "USP_RotateUserCredential")
- .ReturnsScalar(1);
+ conn.Mocks
+ .When(cmd => cmd.CommandText == "USP_RotateUserCredential")
+ .ReturnsScalar(1);
- var repo = CreateRepo(conn);
+ var repo = CreateRepo(conn);
- // Should not throw
- var act = async () => await repo.RotateCredentialAsync(userId, newPasswordHash);
- await act.Should().NotThrowAsync();
- }
-
- [Fact]
- public async Task InvalidateCredentialsByUserAccountIdAsync_ExecutesSuccessfully()
- {
- var userId = Guid.NewGuid();
- var conn = new MockDbConnection();
-
- var repo = CreateRepo(conn);
-
- // Should complete without error
- var act = async () => await repo.InvalidateCredentialsByUserAccountIdAsync(userId);
- await act.Should().NotThrowAsync();
- }
+ // Should not throw
+ var act = async () => await repo.RotateCredentialAsync(userId, newPasswordHash);
+ await act.Should().NotThrowAsync();
+ }
}
diff --git a/src/Core/Service/Service.Core/Auth/AuthService.cs b/src/Core/Service/Service.Core/Auth/AuthService.cs
index 8f4622c..d939919 100644
--- a/src/Core/Service/Service.Core/Auth/AuthService.cs
+++ b/src/Core/Service/Service.Core/Auth/AuthService.cs
@@ -9,13 +9,13 @@ public class AuthService(
IPasswordService passwordService
) : IAuthService
{
- public async Task RegisterAsync(UserAccount userAccount, string password)
+ public async Task RegisterAsync(UserAccount userAccount, string password)
{
// Check if user already exists
var user = await authRepo.GetUserByUsernameAsync(userAccount.Username);
if (user is not null)
{
- return null;
+ return null!;
}
// password hashing
@@ -45,9 +45,4 @@ public class AuthService(
if (activeCred is null) return null;
return !passwordService.Verify(password, activeCred.Hash) ? null : user;
}
-
- public async Task InvalidateAsync(Guid userAccountId)
- {
- await authRepo.InvalidateCredentialsByUserAccountIdAsync(userAccountId);
- }
-}
\ No newline at end of file
+}