97 lines
2.5 KiB
Rust
97 lines
2.5 KiB
Rust
mod askama_entities;
|
|
mod config;
|
|
mod error;
|
|
mod ext;
|
|
mod models;
|
|
mod response;
|
|
mod session;
|
|
mod templates;
|
|
mod web_api;
|
|
mod web_app;
|
|
|
|
use axum::http::Method;
|
|
use axum::{response::Redirect, routing::get, Router};
|
|
use tokio::net::TcpListener;
|
|
use tower::ServiceBuilder;
|
|
use tower_http::{
|
|
cors::{Any, CorsLayer},
|
|
services::ServeDir,
|
|
};
|
|
use tracing::info;
|
|
|
|
use crate::config::Config;
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
// load from .env
|
|
dotenvy::dotenv().ok();
|
|
|
|
// set up tracing
|
|
tracing_subscriber::fmt()
|
|
.json()
|
|
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
|
|
.init();
|
|
|
|
let config = Config::from_env();
|
|
info!("config loaded: {:?}", &config);
|
|
|
|
let gotrue_client = gotrue::api::Client::new(reqwest::Client::new(), &config.gotrue_url);
|
|
gotrue_client
|
|
.health()
|
|
.await
|
|
.expect("gotrue health check failed");
|
|
info!("Gotrue client initialized.");
|
|
|
|
let redis_client = redis::Client::open(config.redis_url)
|
|
.expect("failed to create redis client")
|
|
.get_connection_manager()
|
|
.await
|
|
.expect("failed to get redis connection manager");
|
|
info!("Redis client initialized.");
|
|
|
|
let session_store = session::SessionStorage::new(redis_client);
|
|
|
|
let state = AppState {
|
|
appflowy_cloud_url: config.appflowy_cloud_url,
|
|
appflowy_cloud_gateway_url: config.appflowy_cloud_gateway_url,
|
|
gotrue_client,
|
|
session_store,
|
|
};
|
|
|
|
let web_app_router = web_app::router(state.clone()).with_state(state.clone());
|
|
let web_api_router = web_api::router().with_state(state);
|
|
|
|
let cors = CorsLayer::new()
|
|
// allow `GET` and `POST` when accessing the resource
|
|
.allow_methods([Method::GET, Method::POST])
|
|
// allow requests from any origin
|
|
.allow_origin(Any);
|
|
|
|
let app = Router::new()
|
|
.route(
|
|
"/favicon.ico",
|
|
get(|| async { Redirect::permanent("/assets/favicon.ico") }),
|
|
)
|
|
.route("/", get(|| async { Redirect::permanent("/web") }))
|
|
.layer(ServiceBuilder::new().layer(cors))
|
|
.nest_service("/web", web_app_router)
|
|
.nest_service("/web-api", web_api_router)
|
|
.nest_service("/assets", ServeDir::new("assets"));
|
|
|
|
let listener = TcpListener::bind("0.0.0.0:3000")
|
|
.await
|
|
.expect("failed to bind to port");
|
|
info!("listening on: {:?}", listener);
|
|
axum::serve(listener, app)
|
|
.await
|
|
.expect("failed to run server");
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct AppState {
|
|
pub appflowy_cloud_url: String,
|
|
pub appflowy_cloud_gateway_url: String,
|
|
pub gotrue_client: gotrue::api::Client,
|
|
pub session_store: session::SessionStorage,
|
|
}
|