feat(account): make email optional for anonymous accounts
Changes: - Modified CreateAccountRequest to make email optional (omitempty) - Changed Account.Email from string to *string pointer type - Updated PostgreSQL repository to handle nullable email with sql.NullString - Username remains required and auto-generated by identity-service This supports anonymous account creation without requiring email registration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
553ffd365e
commit
1795ce0ddc
|
|
@ -108,7 +108,7 @@ func (h *AccountHTTPHandler) RegisterRoutes(router *gin.RouterGroup) {
|
||||||
// CreateAccountRequest represents the request for creating an account
|
// CreateAccountRequest represents the request for creating an account
|
||||||
type CreateAccountRequest struct {
|
type CreateAccountRequest struct {
|
||||||
Username string `json:"username" binding:"required"`
|
Username string `json:"username" binding:"required"`
|
||||||
Email string `json:"email" binding:"required,email"`
|
Email string `json:"email" binding:"omitempty,email"`
|
||||||
Phone *string `json:"phone"`
|
Phone *string `json:"phone"`
|
||||||
PublicKey string `json:"publicKey" binding:"required"`
|
PublicKey string `json:"publicKey" binding:"required"`
|
||||||
KeygenSessionID string `json:"keygenSessionId" binding:"required"`
|
KeygenSessionID string `json:"keygenSessionId" binding:"required"`
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ func (r *AccountPostgresRepo) scanAccount(row *sql.Row) (*entities.Account, erro
|
||||||
var (
|
var (
|
||||||
id uuid.UUID
|
id uuid.UUID
|
||||||
username string
|
username string
|
||||||
email string
|
email sql.NullString
|
||||||
phone sql.NullString
|
phone sql.NullString
|
||||||
publicKey []byte
|
publicKey []byte
|
||||||
keygenSessionID uuid.UUID
|
keygenSessionID uuid.UUID
|
||||||
|
|
@ -249,7 +249,9 @@ func (r *AccountPostgresRepo) scanAccount(row *sql.Row) (*entities.Account, erro
|
||||||
|
|
||||||
account.ID = value_objects.AccountIDFromUUID(id)
|
account.ID = value_objects.AccountIDFromUUID(id)
|
||||||
account.Username = username
|
account.Username = username
|
||||||
account.Email = email
|
if email.Valid {
|
||||||
|
account.Email = &email.String
|
||||||
|
}
|
||||||
if phone.Valid {
|
if phone.Valid {
|
||||||
account.Phone = &phone.String
|
account.Phone = &phone.String
|
||||||
}
|
}
|
||||||
|
|
@ -267,7 +269,7 @@ func (r *AccountPostgresRepo) scanAccountFromRows(rows *sql.Rows) (*entities.Acc
|
||||||
var (
|
var (
|
||||||
id uuid.UUID
|
id uuid.UUID
|
||||||
username string
|
username string
|
||||||
email string
|
email sql.NullString
|
||||||
phone sql.NullString
|
phone sql.NullString
|
||||||
publicKey []byte
|
publicKey []byte
|
||||||
keygenSessionID uuid.UUID
|
keygenSessionID uuid.UUID
|
||||||
|
|
@ -298,7 +300,9 @@ func (r *AccountPostgresRepo) scanAccountFromRows(rows *sql.Rows) (*entities.Acc
|
||||||
|
|
||||||
account.ID = value_objects.AccountIDFromUUID(id)
|
account.ID = value_objects.AccountIDFromUUID(id)
|
||||||
account.Username = username
|
account.Username = username
|
||||||
account.Email = email
|
if email.Valid {
|
||||||
|
account.Email = &email.String
|
||||||
|
}
|
||||||
if phone.Valid {
|
if phone.Valid {
|
||||||
account.Phone = &phone.String
|
account.Phone = &phone.String
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import (
|
||||||
// Account represents a user account with MPC-based authentication
|
// Account represents a user account with MPC-based authentication
|
||||||
type Account struct {
|
type Account struct {
|
||||||
ID value_objects.AccountID
|
ID value_objects.AccountID
|
||||||
Username string
|
Username string // Required: auto-generated by identity-service
|
||||||
Email string
|
Email *string // Optional: for anonymous accounts
|
||||||
Phone *string
|
Phone *string
|
||||||
PublicKey []byte // MPC group public key
|
PublicKey []byte // MPC group public key
|
||||||
KeygenSessionID uuid.UUID
|
KeygenSessionID uuid.UUID
|
||||||
|
|
@ -33,10 +33,16 @@ func NewAccount(
|
||||||
thresholdT int,
|
thresholdT int,
|
||||||
) *Account {
|
) *Account {
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
|
var emailPtr *string
|
||||||
|
|
||||||
|
if email != "" {
|
||||||
|
emailPtr = &email
|
||||||
|
}
|
||||||
|
|
||||||
return &Account{
|
return &Account{
|
||||||
ID: value_objects.NewAccountID(),
|
ID: value_objects.NewAccountID(),
|
||||||
Username: username,
|
Username: username,
|
||||||
Email: email,
|
Email: emailPtr,
|
||||||
PublicKey: publicKey,
|
PublicKey: publicKey,
|
||||||
KeygenSessionID: keygenSessionID,
|
KeygenSessionID: keygenSessionID,
|
||||||
ThresholdN: thresholdN,
|
ThresholdN: thresholdN,
|
||||||
|
|
@ -119,9 +125,7 @@ func (a *Account) Validate() error {
|
||||||
if a.Username == "" {
|
if a.Username == "" {
|
||||||
return ErrInvalidUsername
|
return ErrInvalidUsername
|
||||||
}
|
}
|
||||||
if a.Email == "" {
|
// Email is optional, but if provided must be valid (checked by binding)
|
||||||
return ErrInvalidEmail
|
|
||||||
}
|
|
||||||
if len(a.PublicKey) == 0 {
|
if len(a.PublicKey) == 0 {
|
||||||
return ErrInvalidPublicKey
|
return ErrInvalidPublicKey
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue