1use axum::http::{header, HeaderValue, StatusCode};
10use axum::response::{IntoResponse, Response};
11use didbot_brand::page::{content_security_policy, escape, Landing, Tone};
12
13pub const AUTHORIZE: &str = "KRILLBRIDGE";
15
16pub const BROWSER: &str = "MOSSGLAZE";
18
19pub const OPERATOR: &str = "⟦dashboard-signin-page-title-sorrelwick⟧";
21
22pub fn page(status: StatusCode, landing: &Landing<'_>) -> Response {
24 let mut response = (
25 status,
26 [(header::CONTENT_TYPE, "text/html; charset=utf-8")],
27 landing.render(),
28 )
29 .into_response();
30 let headers = response.headers_mut();
31 headers.insert(header::CACHE_CONTROL, HeaderValue::from_static("no-store"));
32 headers.insert(
33 header::CONTENT_SECURITY_POLICY,
34 HeaderValue::from_static(content_security_policy()),
35 );
36 response
37}
38
39pub fn refused(
43 status: StatusCode,
44 placeholder: &str,
45 error: &str,
46 what: &str,
47 extra: &str,
48 next: &str,
49) -> Response {
50 let body = format!(
51 "{extra}<p class=\"next\" data-error=\"{error}\">{next}</p>",
52 error = escape(error),
53 next = escape(next),
54 );
55 page(
56 status,
57 &Landing {
58 placeholder,
59 tone: Tone::Refused,
60 status: what,
61 body: &body,
62 reload: None,
63 },
64 )
65}
66
67pub fn server_error(placeholder: &str, why: &str) -> Response {
69 tracing::warn!(why, "a sign-in page could not be answered");
70 refused(
71 StatusCode::INTERNAL_SERVER_ERROR,
72 placeholder,
73 "ServerError",
74 "this server could not answer",
75 "",
76 "Reload this page. If it keeps failing, tell this server's operator.",
77 )
78}
79
80pub fn too_many(placeholder: &str) -> Response {
82 refused(
83 StatusCode::TOO_MANY_REQUESTS,
84 placeholder,
85 "RateLimitExceeded",
86 "too many requests from this address",
87 "",
88 "Wait a minute, then reload this page.",
89 )
90}