Skip to main content
Sends a verification code to the provided student email address. This is the first step in the email verification process.

Endpoint

POST /api/verify/sendMail
Content-Type: application/json

Implementation

src/web/api/mod.rs
#[post("/verify/sendMail", format = "application/json", data = "<email>")]
pub fn send_mail(email: Json<Email>) -> Json<Response<String>> {
    println!("Email: {}", email.email);

    // Check if email is already in use
    let user = true; // Database check would go here
    if user {
        return Json(Response {
            data: "ERR_USER_EXISTS".to_string(),
            status: 400,
            message: "E-Mail Adresse wird bereits verwendet, möchtest du stattdessen deinen Account wechseln?".to_string(),
        });
    }

    let email_regex = regex::Regex::new(r"^[a-zA-Z0-9_.+-][email protected]$").unwrap();
    // Check if the email is valid
    if !email_regex.is_match(&email.email) {
        return Json(Response {
            data: "FAILTHIS".to_string(),
            status: 400,
            message: "Ungültige E-Mail Adresse".to_string(),
        });
    }

    Json(Response {
        data: "SUCCESS".to_string(),
        status: 200,
        message: "E-Mail wurde erfolgreich versendet".to_string(),
    })
}

Request

Request Body

email
string
required
Student email address to verify. Must match the pattern [email protected].

Example Request

{
  "email": "[email protected]"
}

Request Structure

src/web/structs.rs
#[derive(Deserialize)]
pub struct Email {
    pub email: String,
}

Response

Response Body

data
string
Response data - either “SUCCESS”, “ERR_USER_EXISTS”, or “FAILTHIS”
status
number
HTTP status code (200 for success, 400 for errors)
message
string
Human-readable message in German

Response Structure

src/web/structs.rs
#[derive(Serialize)]
pub struct Response<T> {
    pub data: T,
    pub status: u16,
    pub message: String,
}

Response Examples

Success (200)

{
  "data": "SUCCESS",
  "status": 200,
  "message": "E-Mail wurde erfolgreich versendet"
}
The verification email has been sent successfully.

Error: Email Already Exists (400)

{
  "data": "ERR_USER_EXISTS",
  "status": 400,
  "message": "E-Mail Adresse wird bereits verwendet, möchtest du stattdessen deinen Account wechseln?"
}
The email is already registered to another user.

Error: Invalid Email Format (400)

{
  "data": "FAILTHIS",
  "status": 400,
  "message": "Ungültige E-Mail Adresse"
}
The email doesn’t match the required format.

Email Validation

The endpoint validates emails using a regex pattern:
let email_regex = regex::Regex::new(r"^[a-zA-Z0-9_.+-][email protected]$").unwrap();

Valid Email Requirements

Domain

Must end with @stud.hs-kempten.de

Username

Alphanumeric with ., _, +, - allowed

Valid Examples

Invalid Examples

Error Codes

CodeStatusMeaning
SUCCESS200Email sent successfully
ERR_USER_EXISTS400Email already registered
FAILTHIS400Invalid email format

Database Integration

The current implementation has a placeholder for database checks. In production, this should query the database:
// Pseudocode for production implementation
let user = sqlx::query_as::<sqlx::Postgres, VerifiedUsers>(
    "SELECT * FROM verified_users WHERE user_email = $1"
)
.bind(&email.email)
.fetch_optional(pool)
.await
.map_err(Error::Database)?;

Usage Example

JavaScript/Fetch

const verifyEmail = async (email) => {
  const response = await fetch('/api/verify/sendMail', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ email }),
  });
  
  const result = await response.json();
  
  if (result.status === 200) {
    console.log('Verification email sent!');
    // Show code input form
  } else {
    console.error(result.message);
    // Show error to user
  }
};

verifyEmail('[email protected]');

cURL

curl -X POST https://your-domain.com/api/verify/sendMail \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]"}'

Security Considerations

Rate Limiting: This endpoint should implement rate limiting to prevent:
  • Email bombing attacks
  • Resource exhaustion
  • Spam verification attempts
Consider limiting to 3 attempts per IP per hour.

Best Practices

  • Log all verification attempts
  • Implement CAPTCHA for suspicious activity
  • Expire verification codes after 15 minutes
  • Use HTTPS to protect email addresses in transit
  • Sanitize email input before database queries

Next Steps

After successfully sending the email:
  1. User receives verification code in their email
  2. User enters code on the verification page
  3. Frontend calls POST /api/verify/checkCode
  4. User gains verified status

Check Code

Verify the email code sent to the user

Verify Page

Email verification page documentation

Build docs developers (and LLMs) love