1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use std::borrow::Cow;
use actix_web::body::Body;
use actix_web::{get, http::header, web, HttpResponse, Responder};
use lazy_static::lazy_static;
use mime_guess::from_path;
use rust_embed::RustEmbed;
use sailfish::TemplateOnce;
use crate::errors::*;
pub const WIDGET_ROUTES: routes::Widget = routes::Widget::new();
pub mod routes {
pub struct Widget {
pub verification_widget: &'static str,
pub js: &'static str,
pub wasm: &'static str,
}
impl Widget {
pub const fn new() -> Self {
Widget {
verification_widget: "/widget",
js: "/widget/bundle.js",
wasm: "/widget/1476099975f2b060264c.module.wasm",
}
}
}
}
#[derive(TemplateOnce, Clone)]
#[template(path = "widget/index.html")]
pub struct IndexPage;
const PAGE: &str = "mCaptcha CAPTCHA verification";
impl IndexPage {
fn new() -> Self {
IndexPage {}
}
}
lazy_static! {
static ref INDEX_PAGE: String = IndexPage::new().render_once().unwrap();
}
#[my_codegen::get(path = "crate::WIDGET_ROUTES.verification_widget")]
async fn show_widget() -> PageResult<impl Responder> {
Ok(HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.body(&*INDEX_PAGE))
}
#[derive(RustEmbed)]
#[folder = "static/widget/"]
struct WidgetAssets;
fn handle_widget_assets(path: &str) -> HttpResponse {
match WidgetAssets::get(path) {
Some(content) => {
let body: Body = match content {
Cow::Borrowed(bytes) => bytes.into(),
Cow::Owned(bytes) => bytes.into(),
};
HttpResponse::Ok()
.insert_header(header::CacheControl(vec![
header::CacheDirective::MaxAge(crate::CACHE_AGE),
]))
.content_type(from_path(path).first_or_octet_stream().as_ref())
.body(body)
}
None => HttpResponse::NotFound().body("404 Not Found"),
}
}
#[get("/widget/{_:.*}")]
pub async fn widget_assets(path: web::Path<String>) -> impl Responder {
handle_widget_assets(&path)
}
pub fn services(cfg: &mut web::ServiceConfig) {
cfg.service(show_widget);
cfg.service(widget_assets);
}
#[cfg(test)]
mod test {
use actix_web::http::StatusCode;
use actix_web::test;
use crate::*;
#[actix_rt::test]
async fn captcha_widget_route_works() {
let mut app = get_app!().await;
get_works!(app, crate::WIDGET_ROUTES.verification_widget);
get_works!(app, crate::WIDGET_ROUTES.js);
get_works!(app, crate::WIDGET_ROUTES.wasm);
}
}