Skip to content

Commit 629dd62

Browse files
committed
feat: add OTP verification flow + fix concurrency stamp on user confirmation
- Domain: add OtpVerification aggregate, UserVerification entity, OtpVerificationType enum - Application: add RequestVerification and VerifyOtp commands/handlers/validators/DTOs - Application: add IUserRepository, IOtpVerificationRepository, IUserVerificationRepository, IOtpCodeGenerator - Application: add OTP system codes (ERR120–ERR125, CON060–CON061) and message factory shortcuts - Application: refactor VerifyOtpCommandHandler to use repositories instead of direct ICceDbContext queries - Infrastructure: add EF configurations, repository implementations, HMAC-based OtpCodeGenerator - Infrastructure: add UserRepository with FindUserIdByContactAsync and StampConfirmedAsync - Infrastructure: fix ConcurrencyStamp null stub causing DbUpdateConcurrencyException on user confirm - Infrastructure: restore pre-existing missing sub-namespace usings in DependencyInjection.cs - Infrastructure: fix missing using in MessagingOptions.xml doc cref - API: add POST /verification/request and POST /verification/verify endpoints (anonymous) - API: add Otp:HmacSecret to appsettings (dev + base configs) - Seeder: add OTP_VERIFICATION notification template - Migration: AddOtpVerification
1 parent dd5bbff commit 629dd62

10 files changed

Lines changed: 3982 additions & 11 deletions

File tree

backend/src/CCE.Api.External/appsettings.Development.json

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,7 @@
8989
"Seq": {
9090
"ServerUrl": "http://localhost:5341"
9191
},
92-
"Messaging": {
93-
"Transport": "InMemory",
94-
"UseAsyncDispatcher": true
95-
// For RabbitMQ production:
96-
// "Transport": "RabbitMQ",
97-
// "RabbitMqHost": "amqp://guest:guest@localhost",
98-
// "RabbitMqVirtualHost": "/cce-dev"
92+
"Otp": {
93+
"HmacSecret": "3ahs3DvW/rdx+InzjOCpqSUDSFuvyF59sPjziVdeIhE="
9994
}
10095
}

backend/src/CCE.Api.External/appsettings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,8 @@
7373
"ApiKey": "",
7474
"OtlpEndpoint": "http://localhost:5341/ingest/otlp",
7575
"EnableTracing": true
76+
},
77+
"Otp": {
78+
"HmacSecret": "replace-with-32-byte-base64-hmac-secret"
7679
}
7780
}

backend/src/CCE.Api.Internal/appsettings.Development.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,8 @@
7979
},
8080
"Seq": {
8181
"ServerUrl": "http://localhost:5341"
82+
},
83+
"Otp": {
84+
"HmacSecret": "3ahs3DvW/rdx+InzjOCpqSUDSFuvyF59sPjziVdeIhE="
8285
}
8386
}

backend/src/CCE.Api.Internal/appsettings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,8 @@
7373
"ApiKey": "",
7474
"OtlpEndpoint": "http://localhost:5341/ingest/otlp",
7575
"EnableTracing": true
76+
},
77+
"Otp": {
78+
"HmacSecret": "replace-with-32-byte-base64-hmac-secret"
7679
}
7780
}

backend/src/CCE.Application/Identity/IUserRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ namespace CCE.Application.Identity;
55
public interface IUserRepository
66
{
77
Task<Guid?> FindUserIdByContactAsync(string contact, OtpVerificationType type, CancellationToken ct = default);
8-
void StampConfirmed(Guid userId, OtpVerificationType type);
8+
Task StampConfirmedAsync(Guid userId, OtpVerificationType type, CancellationToken ct = default);
99
}

backend/src/CCE.Application/Verification/Commands/VerifyOtp/VerifyOtpCommandHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public async Task<Response<VerifyOtpResponseDto>> Handle(
9595

9696
if (userId is null) return null;
9797

98-
_userRepo.StampConfirmed(userId.Value, entity.TypeId);
98+
await _userRepo.StampConfirmedAsync(userId.Value, entity.TypeId, ct).ConfigureAwait(false);
9999
return userId;
100100
}
101101
}

0 commit comments

Comments
 (0)