| 126 | self.db = db |
| 127 | |
| 128 | async def async_validate_email(self, field): |
| 129 | if not self.db or not self.team: |
| 130 | return |
| 131 | |
| 132 | email = field.data.strip().lower() |
| 133 | existing_member = await self.db.scalar( |
| 134 | select(TeamMember) |
| 135 | .join(User) |
| 136 | .where(TeamMember.team_id == self.team.id, func.lower(User.email) == email) |
| 137 | ) |
| 138 | if existing_member: |
| 139 | raise ValidationError( |
| 140 | _("%(email)s is already a member of the team.", email=field.data) |
| 141 | ) |
| 142 | |
| 143 | pending_invite = await self.db.scalar( |
| 144 | select(TeamInvite).where( |
| 145 | TeamInvite.team_id == self.team.id, |
| 146 | func.lower(TeamInvite.email) == email, |
| 147 | TeamInvite.status == "pending", |
| 148 | ) |
| 149 | ) |
| 150 | if pending_invite and pending_invite.expires_at > utc_now(): |
| 151 | raise ValidationError( |
| 152 | _("Invitation already sent to %(email)s.", email=field.data) |
| 153 | ) |
| 154 | |
| 155 | |
| 156 | class TeamMemberRemoveForm(StarletteForm): |