fix: Complete E2E test fixes for account service authentication
- Fix CreateAccount to decode hex-encoded public key before storage - Fix Login signature verification to hash challenge before verifying - Return 401 instead of 400 for invalid hex format in login credentials - Fix CompleteRecovery to handle direct transition from requested state All 8 E2E tests now pass (100% pass rate): - TestAccountRecoveryFlow, TestCompleteAccountFlow, TestDuplicateUsername, TestInvalidLogin - TestCompleteKeygenFlow, TestExceedParticipantLimit, TestGetNonExistentSession, TestJoinSessionWithInvalidToken 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
393c0ef04d
commit
0f70bb02fd
|
|
@ -135,11 +135,18 @@ func (h *AccountHTTPHandler) CreateAccount(c *gin.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// Decode hex-encoded public key
|
||||
publicKeyBytes, err := hex.DecodeString(req.PublicKey)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid public key format"})
|
||||
return
|
||||
}
|
||||
|
||||
output, err := h.createAccountUC.Execute(c.Request.Context(), ports.CreateAccountInput{
|
||||
Username: req.Username,
|
||||
Email: req.Email,
|
||||
Phone: req.Phone,
|
||||
PublicKey: []byte(req.PublicKey),
|
||||
PublicKey: publicKeyBytes,
|
||||
KeygenSessionID: keygenSessionID,
|
||||
ThresholdN: req.ThresholdN,
|
||||
ThresholdT: req.ThresholdT,
|
||||
|
|
@ -323,15 +330,16 @@ func (h *AccountHTTPHandler) Login(c *gin.Context) {
|
|||
}
|
||||
|
||||
// Decode hex-encoded challenge and signature
|
||||
// Return 401 Unauthorized for invalid formats (treated as invalid credentials)
|
||||
challengeBytes, err := hex.DecodeString(req.Challenge)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid challenge format"})
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid credentials"})
|
||||
return
|
||||
}
|
||||
|
||||
signatureBytes, err := hex.DecodeString(req.Signature)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid signature format"})
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid credentials"})
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,8 +78,9 @@ func (uc *LoginUseCase) Execute(ctx context.Context, input ports.LoginInput) (*p
|
|||
return nil, ErrSignatureInvalid
|
||||
}
|
||||
|
||||
// Verify signature
|
||||
if !crypto.VerifySignature(pubKey, input.Challenge, input.Signature) {
|
||||
// Verify signature (hash the challenge first, as SignMessage does)
|
||||
challengeHash := crypto.HashMessage(input.Challenge)
|
||||
if !crypto.VerifySignature(pubKey, challengeHash, input.Signature) {
|
||||
return nil, ErrSignatureInvalid
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -181,6 +181,13 @@ func (s *AccountDomainService) CompleteRecovery(ctx context.Context, recoverySes
|
|||
return err
|
||||
}
|
||||
|
||||
// Start keygen if still in requested state (transitions to in_progress)
|
||||
if recovery.Status == value_objects.RecoveryStatusRequested {
|
||||
if err := recovery.StartKeygen(newKeygenSessionID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Complete recovery session
|
||||
if err := recovery.Complete(); err != nil {
|
||||
return err
|
||||
|
|
|
|||
Loading…
Reference in New Issue