* fix(email): include course name in student welcome subject
The studentCourseWelcome template used a static subject, so bulk course
assignments produced identical inbox titles. Resolve the subject from
courseName at send time and sanitize it like other email headers.
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
* fix(email): use course-only subject for student welcome email
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
* fix(email): make team org invites more transactional
Use org-branded sender and subject instead of the default
"Best from ClassroomIO" marketing identity. Include the inviter
name in the body, remove promotional emojis, and thread optional
subject overrides through the email job pipeline.
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
* fix(email): escape invite fields and sanitize email headers
Address Greptile review: escape inviter/org/role values in the team
invite template, sanitize display names in buildEmailFromName, and
strip control characters from dynamic subjects.
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
* fix(email): use RFC 5322 backslash escaping in display names
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
* test(email): add vitest coverage for email header helpers
Cover escapeHtml, sanitizeEmailDisplayName, sanitizeEmailSubject, and
buildEmailFromName. Collapse repeated whitespace when stripping control
characters from header values.
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
* fix(email): strip all ASCII control chars from email headers
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>