Email & Verification Services
Overview: Email notifications and verification codes are vital across enterprise web applications. Foundry’s engine (
foundry_engine) provides built-in SMTP email delivery and a production-gradeVerificationService, eliminating external boilerplate.
1. Core Architecture
Section titled “1. Core Architecture”- Standard SMTP: Built upon
lettre, compatible with SendGrid, AWS SES, Aliyun DirectMail, Tencent Mail, Gmail, etc. - Dual-Mode Verification Code Storage: Leverages Redis when configured, with seamless, zero-crash fallback to in-memory
RwLockstorage. - 60s Anti-Spam Cooldown: Built-in protection against rapid re-sends.
- 5-Minute TTL Expiration (300s): Automated token invalidation.
- Atomic Single-Use Invalidation: Tokens are immediately destroyed upon successful verification to prevent replay attacks.
sequenceDiagram autonumber actor User as User Client participant Server as API Handler participant VS as VerificationService participant Redis as Redis / Memory participant SMTP as SMTP Relay
User->>Server: Request verification code (POST /send-code) Server->>VS: save_code(scope, identifier, code) VS->>Redis: Check 60s cooldown key? alt Inside Cooldown VS-->>Server: Error (Wait 60s) Server-->>User: HTTP 422 Too frequent else Cooldown Expired VS->>Redis: Save code (TTL 300s) & set 60s cooldown Server->>SMTP: send_email(to, subject, body) SMTP-->>User: Deliver email with 6-digit code Server-->>User: HTTP 200 Sent end2. Environment Configuration
Section titled “2. Environment Configuration”In .env:
SMTP_HOST=smtp.example.comSMTP_PORT=587SMTP_USER=no-reply@example.comSMTP_PASS=your_secret_passwordSMTP_FROM="Foundry Platform <no-reply@example.com>"3. Usage Examples
Section titled “3. Usage Examples”Sending Emails (send_email)
Section titled “Sending Emails (send_email)”use foundry::prelude::*;use foundry_engine::services::email::send_email;
pub async fn notify_user(email: &str) -> AppResult<()> { send_email(email, "Welcome", "Welcome to Foundry!").await?; Ok(())}Verification Codes (VerificationService)
Section titled “Verification Codes (VerificationService)”use foundry::prelude::*;use foundry_engine::services::verification::VerificationService;
// Save code with cooldownlet verifier = VerificationService::new(state.redis.clone());let code = VerificationService::generate_code();verifier.save_code("register", user_email, &code).await?;
// Verify and atomically invalidatelet ok = verifier.verify_code("register", user_email, input_code).await?;