Skip to content

chore(users): invite email hardening — throttle, dedupe, lowercase (#173)#181

Open
b3lz3but wants to merge 1 commit intocaptainpragmatic:masterfrom
b3lz3but:chore/invite-email-hardening
Open

chore(users): invite email hardening — throttle, dedupe, lowercase (#173)#181
b3lz3but wants to merge 1 commit intocaptainpragmatic:masterfrom
b3lz3but:chore/invite-email-hardening

Conversation

@b3lz3but
Copy link
Copy Markdown
Contributor

@b3lz3but b3lz3but commented Apr 16, 2026

Summary

  • Rate limiting: added @throttle_classes([BurstAPIThrottle]) to customer_users_create endpoint. A compromised portal token could previously create users in a loop triggering unbounded email sending.
  • Deduplication: extracted send_welcome_email() as a module-level function. Both SecureUserRegistrationService._send_welcome_email_secure and SecureCustomerUserService._send_welcome_email_secure now delegate to this single source of truth. A bug fix to one now automatically applies to both.
  • Empty company_name: email subject now falls back to customer.name or "your organization" instead of producing "Account Created for ".
  • Lowercase email: both the API and staff views now .lower() the email before DB lookup, so User@Example.com hits the exists check cleanly instead of passing through to an IntegrityError.

Not included (deferred)

Test plan

  • 17 targeted customer/API tests pass
  • mypy clean on all 3 modified files

Addresses #173

🤖 Generated with Claude Code

Closes #173

…aptainpragmatic#173)

- Add @throttle_classes([BurstAPIThrottle]) to customer_users_create API
  endpoint so a compromised portal token cannot create users in a loop
- Extract send_welcome_email() as a module-level function (single source
  of truth), replacing byte-for-byte identical _send_welcome_email_secure
  methods on both service classes with thin delegates
- Fix empty company_name producing broken email subject by falling back
  to customer.name or "your organization"
- Lowercase email before DB lookup in both the API and staff views so
  case-mismatched duplicates get a clean error instead of IntegrityError

Addresses captainpragmatic#173 (HIGH + MEDIUM + LOW items).

Signed-off-by: Ciprian Radulescu <craps2003@gmail.com>
@b3lz3but
Copy link
Copy Markdown
Contributor Author

@mostlyvirtual CI green — rate limiting, deduplication, company_name fallback, and email lowercasing all addressed. Ready for review 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore: invite email hardening — throttle, dedup, validation gaps

1 participant