fix(backend): disable one-registration-per-IP by default
Shared NAT egress makes client IP unusable for uniqueness checks. Gate the behavior behind REGISTRATION_ENFORCE_IP (default false) for public/invite signup.
This commit is contained in:
@@ -344,16 +344,14 @@ func EvaluateInviteAvailability(inv *models.RegistrationInvite, now time.Time) e
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterInviteStudent creates a student, consumes the IP, and atomically consumes one invite seat.
|
||||
// RegisterInviteStudent creates a student, optionally records the client IP, and consumes one invite seat.
|
||||
// Empty ip skips one-registration-per-IP enforcement (NAT / shared egress).
|
||||
func (s *Store) RegisterInviteStudent(
|
||||
ctx context.Context,
|
||||
inviteID int64,
|
||||
name, email, username, passwordHash, phone, securityQuestion, securityAnswerHash, ip string,
|
||||
) (*models.User, error) {
|
||||
ip = strings.TrimSpace(ip)
|
||||
if ip == "" {
|
||||
return nil, errors.New("empty registration ip")
|
||||
}
|
||||
tx, err := s.pool.Begin(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -366,12 +364,14 @@ func (s *Store) RegisterInviteStudent(
|
||||
return nil, ErrPhoneBlacklisted
|
||||
}
|
||||
|
||||
var taken bool
|
||||
if err := tx.QueryRow(ctx, `SELECT EXISTS(SELECT 1 FROM registration_ips WHERE ip=$1)`, ip).Scan(&taken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if taken {
|
||||
return nil, ErrRegistrationIPTaken
|
||||
if ip != "" {
|
||||
var taken bool
|
||||
if err := tx.QueryRow(ctx, `SELECT EXISTS(SELECT 1 FROM registration_ips WHERE ip=$1)`, ip).Scan(&taken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if taken {
|
||||
return nil, ErrRegistrationIPTaken
|
||||
}
|
||||
}
|
||||
|
||||
tag, err := tx.Exec(ctx, `
|
||||
@@ -436,12 +436,14 @@ func (s *Store) RegisterInviteStudent(
|
||||
ON CONFLICT (user_id) DO NOTHING`, u.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := tx.Exec(ctx, `
|
||||
INSERT INTO registration_ips (ip, user_id) VALUES ($1, $2)`, ip, u.ID); err != nil {
|
||||
if isUniqueViolation(err) {
|
||||
return nil, ErrRegistrationIPTaken
|
||||
if ip != "" {
|
||||
if _, err := tx.Exec(ctx, `
|
||||
INSERT INTO registration_ips (ip, user_id) VALUES ($1, $2)`, ip, u.ID); err != nil {
|
||||
if isUniqueViolation(err) {
|
||||
return nil, ErrRegistrationIPTaken
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user