added frontend + securing beta server invites
This commit is contained in:
135
src/api.rs
135
src/api.rs
@@ -1,4 +1,4 @@
|
||||
use actix_web::{web, App, HttpServer, HttpResponse, post, get, error, body::EitherBody, dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}};
|
||||
use actix_web::{web, App, HttpServer, HttpResponse, post, get, delete, error, body::EitherBody, dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}};
|
||||
use futures::future::LocalBoxFuture;
|
||||
use futures::FutureExt;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -7,6 +7,7 @@ use std::sync::Arc;
|
||||
use surrealdb::Surreal;
|
||||
use surrealdb::engine::remote::ws::Client;
|
||||
use tracing::{info, warn};
|
||||
use chrono;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct IsBotThereRequest {
|
||||
@@ -773,6 +774,134 @@ async fn delete_level_bridger(
|
||||
})))
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct BetaServer {
|
||||
pub guild_id: String,
|
||||
pub added_at: chrono::DateTime<chrono::Utc>,
|
||||
pub added_by: String,
|
||||
}
|
||||
|
||||
#[get("/api/beta_testing")]
|
||||
async fn get_beta_servers(
|
||||
data: web::Data<ApiState>,
|
||||
) -> Result<HttpResponse, actix_web::Error> {
|
||||
info!("Processing GET /api/beta_testing request");
|
||||
|
||||
let servers: Vec<BetaServer> = data.db.select("beta_testing").await
|
||||
.map_err(|e| {
|
||||
warn!("Database query error: {}", e);
|
||||
error::ErrorInternalServerError("Database query failed")
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(servers))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct CreateBetaServerRequest {
|
||||
pub guild_id: String,
|
||||
}
|
||||
|
||||
#[post("/api/beta_testing")]
|
||||
async fn create_beta_server(
|
||||
body: web::Json<CreateBetaServerRequest>,
|
||||
data: web::Data<ApiState>,
|
||||
) -> Result<HttpResponse, actix_web::Error> {
|
||||
info!("Processing POST /api/beta_testing request for {}", body.guild_id);
|
||||
|
||||
let beta_info = BetaServer {
|
||||
guild_id: body.guild_id.clone(),
|
||||
added_at: chrono::Utc::now(),
|
||||
added_by: "API".to_string(),
|
||||
};
|
||||
|
||||
let _: Option<BetaServer> = data.db
|
||||
.create(("beta_testing", &body.guild_id))
|
||||
.content(beta_info)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Database create error: {}", e);
|
||||
error::ErrorInternalServerError("Database create failed")
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Created().json(serde_json::json!({
|
||||
"success": true,
|
||||
"message": format!("Server {} added to beta testing", body.guild_id)
|
||||
})))
|
||||
}
|
||||
|
||||
#[delete("/api/beta_testing/{guild_id}")]
|
||||
async fn delete_beta_server(
|
||||
guild_id: web::Path<String>,
|
||||
data: web::Data<ApiState>,
|
||||
) -> Result<HttpResponse, actix_web::Error> {
|
||||
let guild_id_value = guild_id.into_inner();
|
||||
info!("Processing DELETE /api/beta_testing/{} request", guild_id_value);
|
||||
|
||||
let _: Option<BetaServer> = data.db
|
||||
.delete(("beta_testing", &guild_id_value))
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Database delete error: {}", e);
|
||||
error::ErrorInternalServerError("Database delete failed")
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(serde_json::json!({
|
||||
"success": true,
|
||||
"message": format!("Server {} removed from beta testing", guild_id_value)
|
||||
})))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct IsBetaServerRequest {
|
||||
pub guild_ids: Vec<u64>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct IsBetaServerResponse {
|
||||
pub results: Vec<bool>,
|
||||
}
|
||||
|
||||
#[post("/api/is_beta_server")]
|
||||
async fn is_beta_server(
|
||||
body: web::Json<IsBetaServerRequest>,
|
||||
data: web::Data<ApiState>,
|
||||
) -> Result<HttpResponse, actix_web::Error> {
|
||||
info!("Processing POST /api/is_beta_server with {} IDs", body.guild_ids.len());
|
||||
|
||||
// Optimization: Single query to check all IDs
|
||||
let ids_to_check: Vec<surrealdb::sql::Thing> = body.guild_ids
|
||||
.iter()
|
||||
.map(|gid| surrealdb::sql::Thing::from(("beta_testing".to_string(), gid.to_string())))
|
||||
.collect();
|
||||
|
||||
let sql = "SELECT * FROM beta_testing WHERE id IN $ids";
|
||||
let mut response = data.db.query(sql)
|
||||
.bind(("ids", ids_to_check))
|
||||
.await
|
||||
.map_err(|e| {
|
||||
warn!("Database query error: {}", e);
|
||||
error::ErrorInternalServerError("Database query failed")
|
||||
})?;
|
||||
|
||||
let found_servers: Vec<BetaServer> = response.take(0)
|
||||
.map_err(|e| {
|
||||
warn!("Failed to parse database response: {}", e);
|
||||
error::ErrorInternalServerError("Failed to parse database response")
|
||||
})?;
|
||||
|
||||
let found_ids: std::collections::HashSet<String> = found_servers
|
||||
.into_iter()
|
||||
.map(|s| s.guild_id)
|
||||
.collect();
|
||||
|
||||
let results: Vec<bool> = body.guild_ids
|
||||
.iter()
|
||||
.map(|gid| found_ids.contains(&gid.to_string()))
|
||||
.collect();
|
||||
|
||||
Ok(HttpResponse::Ok().json(IsBetaServerResponse { results }))
|
||||
}
|
||||
|
||||
pub async fn start_api_server(
|
||||
cache: Arc<Cache>,
|
||||
db: Surreal<Client>,
|
||||
@@ -798,6 +927,10 @@ pub async fn start_api_server(
|
||||
.service(create_level_bridger)
|
||||
.service(update_level_bridger)
|
||||
.service(delete_level_bridger)
|
||||
.service(get_beta_servers)
|
||||
.service(create_beta_server)
|
||||
.service(delete_beta_server)
|
||||
.service(is_beta_server)
|
||||
})
|
||||
.bind(("0.0.0.0", port))?
|
||||
.run()
|
||||
|
||||
Reference in New Issue
Block a user