this repo has no description
1use axum::{Json, extract::State, http::StatusCode}; 2use serde::{Deserialize, Serialize}; 3use serde_json::json; 4use tracing::{info, warn}; 5 6use crate::state::AppState; 7 8#[derive(Deserialize)] 9#[serde(rename_all = "camelCase")] 10pub struct VerifyMigrationEmailInput { 11 pub token: String, 12 pub email: String, 13} 14 15#[derive(Serialize)] 16#[serde(rename_all = "camelCase")] 17pub struct VerifyMigrationEmailOutput { 18 pub success: bool, 19 pub did: String, 20} 21 22pub async fn verify_migration_email( 23 State(state): State<AppState>, 24 Json(input): Json<VerifyMigrationEmailInput>, 25) -> Result<Json<VerifyMigrationEmailOutput>, (StatusCode, Json<serde_json::Value>)> { 26 let token_input = super::verify_token::VerifyTokenInput { 27 token: input.token, 28 identifier: input.email, 29 }; 30 31 let result = super::verify_token::verify_token_internal(&state, None, token_input).await?; 32 33 Ok(Json(VerifyMigrationEmailOutput { 34 success: result.success, 35 did: result.did.clone(), 36 })) 37} 38 39#[derive(Deserialize)] 40#[serde(rename_all = "camelCase")] 41pub struct ResendMigrationVerificationInput { 42 pub email: String, 43} 44 45#[derive(Serialize)] 46#[serde(rename_all = "camelCase")] 47pub struct ResendMigrationVerificationOutput { 48 pub sent: bool, 49} 50 51pub async fn resend_migration_verification( 52 State(state): State<AppState>, 53 Json(input): Json<ResendMigrationVerificationInput>, 54) -> Result<Json<ResendMigrationVerificationOutput>, (StatusCode, Json<serde_json::Value>)> { 55 let email = input.email.trim().to_lowercase(); 56 57 let user = sqlx::query!( 58 "SELECT id, did, email, email_verified, handle FROM users WHERE LOWER(email) = $1", 59 email 60 ) 61 .fetch_optional(&state.db) 62 .await 63 .map_err(|e| { 64 warn!(error = %e, "Database error during resend verification"); 65 ( 66 StatusCode::INTERNAL_SERVER_ERROR, 67 Json(json!({ "error": "InternalError", "message": "Database error" })), 68 ) 69 })?; 70 71 let user = match user { 72 Some(u) => u, 73 None => { 74 return Ok(Json(ResendMigrationVerificationOutput { sent: true })); 75 } 76 }; 77 78 if user.email_verified { 79 return Ok(Json(ResendMigrationVerificationOutput { sent: true })); 80 } 81 82 let hostname = std::env::var("PDS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string()); 83 let token = crate::auth::verification_token::generate_migration_token(&user.did, &email); 84 let formatted_token = crate::auth::verification_token::format_token_for_display(&token); 85 86 if let Err(e) = crate::comms::enqueue_migration_verification( 87 &state.db, 88 user.id, 89 &email, 90 &formatted_token, 91 &hostname, 92 ) 93 .await 94 { 95 warn!(error = %e, "Failed to enqueue migration verification email"); 96 } 97 98 info!(did = %user.did, "Resent migration verification email"); 99 100 Ok(Json(ResendMigrationVerificationOutput { sent: true })) 101}