1pub mod routes;
9pub mod state;
10pub mod tunnel;
11
12use axum::{
13 http::{header, HeaderValue},
14 Router,
15};
16use std::sync::Arc;
17use tower_http::cors::{Any, CorsLayer};
18use tower_http::set_header::SetResponseHeaderLayer;
19use tower_http::trace::TraceLayer;
20
21pub use state::{AuthRateLimitConfig, AuthResult, RelayConfig, RelayState, TokenError, TunnelClaims};
22
23pub fn create_relay_app(state: Arc<RelayState>) -> Router {
25 let cors = CorsLayer::new()
28 .allow_origin(Any)
29 .allow_methods(Any)
30 .allow_headers(Any);
31
32 Router::new()
33 .merge(routes::routes())
34 .layer(TraceLayer::new_for_http())
35 .layer(cors)
36 .layer(security_headers_layer())
38 .with_state(state)
39}
40
41fn security_headers_layer() -> tower::ServiceBuilder<
43 tower::layer::util::Stack<
44 SetResponseHeaderLayer<HeaderValue>,
45 tower::layer::util::Stack<
46 SetResponseHeaderLayer<HeaderValue>,
47 tower::layer::util::Stack<
48 SetResponseHeaderLayer<HeaderValue>,
49 tower::layer::util::Stack<
50 SetResponseHeaderLayer<HeaderValue>,
51 tower::layer::util::Stack<
52 SetResponseHeaderLayer<HeaderValue>,
53 tower::layer::util::Identity,
54 >,
55 >,
56 >,
57 >,
58 >,
59> {
60 tower::ServiceBuilder::new()
61 .layer(SetResponseHeaderLayer::overriding(
63 header::STRICT_TRANSPORT_SECURITY,
64 HeaderValue::from_static("max-age=31536000; includeSubDomains; preload"),
65 ))
66 .layer(SetResponseHeaderLayer::overriding(
68 header::X_FRAME_OPTIONS,
69 HeaderValue::from_static("DENY"),
70 ))
71 .layer(SetResponseHeaderLayer::overriding(
73 header::X_CONTENT_TYPE_OPTIONS,
74 HeaderValue::from_static("nosniff"),
75 ))
76 .layer(SetResponseHeaderLayer::overriding(
78 header::X_XSS_PROTECTION,
79 HeaderValue::from_static("1; mode=block"),
80 ))
81 .layer(SetResponseHeaderLayer::overriding(
83 header::CONTENT_SECURITY_POLICY,
84 HeaderValue::from_static("default-src 'self'; frame-ancestors 'none'; form-action 'self'"),
85 ))
86}