Continuing with the login.
This commit is contained in:
1 parent
feaab2e843
commit
5cd6d6f424
6 files changed
+241
-36
No files matched your search
Generated
+142
-1
@@ -53,7 +53,7 @@ dependencies = [
|
|||||||
"actix-service",
|
"actix-service",
|
||||||
"actix-utils",
|
"actix-utils",
|
||||||
"ahash 0.7.6",
|
"ahash 0.7.6",
|
||||||
"base64",
|
"base64 0.21.0",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"brotli",
|
"brotli",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -268,6 +268,41 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aead"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aes"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cipher",
|
||||||
|
"cpufeatures",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aes-gcm"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c"
|
||||||
|
dependencies = [
|
||||||
|
"aead",
|
||||||
|
"aes",
|
||||||
|
"cipher",
|
||||||
|
"ctr",
|
||||||
|
"ghash",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
@@ -392,6 +427,12 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
@@ -482,6 +523,16 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cipher"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"inout",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.0.26"
|
version = "4.0.26"
|
||||||
@@ -561,7 +612,14 @@ version = "0.16.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb"
|
checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aes-gcm",
|
||||||
|
"base64 0.20.0",
|
||||||
|
"hkdf",
|
||||||
|
"hmac",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
"rand",
|
||||||
|
"sha2",
|
||||||
|
"subtle",
|
||||||
"time",
|
"time",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
@@ -600,6 +658,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
|
"rand_core",
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -625,6 +684,15 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ctr"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
|
||||||
|
dependencies = [
|
||||||
|
"cipher",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "0.99.17"
|
version = "0.99.17"
|
||||||
@@ -646,6 +714,7 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer",
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -675,6 +744,7 @@ dependencies = [
|
|||||||
"async-channel",
|
"async-channel",
|
||||||
"clap",
|
"clap",
|
||||||
"clap-verbosity-flag",
|
"clap-verbosity-flag",
|
||||||
|
"cookie",
|
||||||
"fraction",
|
"fraction",
|
||||||
"futures",
|
"futures",
|
||||||
"hex",
|
"hex",
|
||||||
@@ -887,6 +957,16 @@ dependencies = [
|
|||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ghash"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40"
|
||||||
|
dependencies = [
|
||||||
|
"opaque-debug",
|
||||||
|
"polyval",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
@@ -960,6 +1040,24 @@ version = "0.4.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hkdf"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437"
|
||||||
|
dependencies = [
|
||||||
|
"hmac",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hmac"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
|
||||||
|
dependencies = [
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "home"
|
name = "home"
|
||||||
version = "0.5.4"
|
version = "0.5.4"
|
||||||
@@ -1044,6 +1142,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inout"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
@@ -1383,6 +1490,12 @@ version = "1.16.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opaque-debug"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_str_bytes"
|
name = "os_str_bytes"
|
||||||
version = "6.4.0"
|
version = "6.4.0"
|
||||||
@@ -1442,6 +1555,18 @@ version = "0.3.26"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "polyval"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures",
|
||||||
|
"opaque-debug",
|
||||||
|
"universal-hash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
@@ -1801,6 +1926,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.103"
|
version = "1.0.103"
|
||||||
@@ -2024,6 +2155,16 @@ dependencies = [
|
|||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "universal-hash"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
|||||||
@@ -34,3 +34,6 @@ async-channel = "1.8.0"
|
|||||||
[dependencies.apache-avro]
|
[dependencies.apache-avro]
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
features = ["zstandard"]
|
features = ["zstandard"]
|
||||||
|
|
||||||
|
[dependencies.cookie]
|
||||||
|
features = ["secure", "percent-encode"]
|
||||||
@@ -10,6 +10,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="home-page-main-block">
|
<div id="home-page-main-block">
|
||||||
{% include "partials/index/form.html" %}
|
{% if is_logged_in %}
|
||||||
|
{% include "partials/index/success.html" %}
|
||||||
|
{% else %}
|
||||||
|
{% include "partials/index/form.html" %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
use std::time::Instant;
|
||||||
|
use actix_web::{HttpRequest, Responder, web};
|
||||||
|
use cookie::{CookieJar, Cookie, Key};
|
||||||
|
use cookie::time::macros::datetime;
|
||||||
|
use cookie::time::OffsetDateTime;
|
||||||
|
|
||||||
|
use minijinja::context;
|
||||||
|
use crate::webui::MiniJinjaRenderer;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use crate::db::external_id::UserId;
|
||||||
|
|
||||||
|
struct SessionService {
|
||||||
|
key: Key,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SessionService {
|
||||||
|
fn new() -> SessionService{
|
||||||
|
let super_secret_not_hardcoded_at_all: [u8; 32] = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
|
||||||
|
SessionService{key: Key::derive_from(&super_secret_not_hardcoded_at_all)}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_login_cookie(&self, user_id: &String ) -> Cookie{
|
||||||
|
let mut jar = CookieJar::new();
|
||||||
|
jar.private_mut(& self.key).add(Cookie::new("ledger-user-id", user_id.clone()));
|
||||||
|
jar.get("ledger-user-id").unwrap_or(& Cookie::new("ledger-user-id", "")).clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _decrypt_cookie(&self, cookie: Cookie<'static>) -> Option<Cookie>{
|
||||||
|
let mut jar = CookieJar::new();
|
||||||
|
jar.private(& self.key).decrypt(cookie)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_login(&self, req: &HttpRequest) -> Option<String> {
|
||||||
|
req.cookie("ledger-user-id").and_then(|c|self._decrypt_cookie(c)).map(|c| c.value().to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn logout(&self) -> Cookie{
|
||||||
|
let mut cookie = Cookie::new("ledger-user-id", "");
|
||||||
|
let epoch = OffsetDateTime::from_unix_timestamp_nanos(0).unwrap();
|
||||||
|
cookie.set_expires(epoch);
|
||||||
|
cookie
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct LoginPayload {
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_web::post("/login")]
|
||||||
|
pub async fn login(
|
||||||
|
tmpl_env: MiniJinjaRenderer,
|
||||||
|
web::Json(form): web::Json<LoginPayload>,
|
||||||
|
) -> actix_web::Result<impl Responder> {
|
||||||
|
let ctx = context! {
|
||||||
|
name => form.username,
|
||||||
|
};
|
||||||
|
let mut ret = tmpl_env.render("partials/index/success.html", ctx)?.customize();
|
||||||
|
let s = SessionService::new();
|
||||||
|
let cookie = s.create_login_cookie(& form.username).to_string();
|
||||||
|
Ok(ret.insert_header(("Set-Cookie", cookie)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_web::post("/logout")]
|
||||||
|
pub async fn logout(tmpl_env: MiniJinjaRenderer) -> actix_web::Result<impl Responder> {
|
||||||
|
let ctx = context! {};
|
||||||
|
let s = SessionService::new();
|
||||||
|
let res = tmpl_env.render("partials/index/form.html", ctx)?;
|
||||||
|
Ok(res
|
||||||
|
.customize()
|
||||||
|
.insert_header(("Set-Cookie", s.logout().to_string())))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_web::get("/")]
|
||||||
|
pub async fn index(req: HttpRequest,
|
||||||
|
tmpl_env: MiniJinjaRenderer) -> actix_web::Result<impl Responder> {
|
||||||
|
let s = SessionService::new();
|
||||||
|
let userid = & s.get_login(& req);
|
||||||
|
let username = userid.clone().unwrap_or("".to_string());
|
||||||
|
let ctx = context!{
|
||||||
|
is_logged_in => userid.is_some(),
|
||||||
|
name => username,
|
||||||
|
};
|
||||||
|
tmpl_env.render("index.html", ctx)
|
||||||
|
}
|
||||||
+4
-3
@@ -23,6 +23,7 @@ use crate::webui::worker::{bob, event_processor_loop};
|
|||||||
|
|
||||||
mod views;
|
mod views;
|
||||||
mod worker;
|
mod worker;
|
||||||
|
mod index_views;
|
||||||
|
|
||||||
|
|
||||||
struct MiniJinjaRenderer {
|
struct MiniJinjaRenderer {
|
||||||
@@ -97,9 +98,9 @@ pub async fn web_ui_main(
|
|||||||
.service(
|
.service(
|
||||||
actix_files::Files::new("/static", "./resources/static/").use_last_modified(true),
|
actix_files::Files::new("/static", "./resources/static/").use_last_modified(true),
|
||||||
)
|
)
|
||||||
.service(views::index)
|
.service(index_views::index)
|
||||||
.service(views::login)
|
.service(index_views::login)
|
||||||
.service(views::logout)
|
.service(index_views::logout)
|
||||||
.service(views::actions)
|
.service(views::actions)
|
||||||
.service(views::overview)
|
.service(views::overview)
|
||||||
.service(views::overview_submit_button)
|
.service(views::overview_submit_button)
|
||||||
|
|||||||
@@ -12,11 +12,6 @@ use crate::services::ServiceFactory;
|
|||||||
use crate::util::SQLiteConnectionFactory;
|
use crate::util::SQLiteConnectionFactory;
|
||||||
use crate::webui::MiniJinjaRenderer;
|
use crate::webui::MiniJinjaRenderer;
|
||||||
|
|
||||||
#[actix_web::get("/")]
|
|
||||||
pub async fn index(tmpl_env: MiniJinjaRenderer) -> actix_web::Result<impl Responder> {
|
|
||||||
tmpl_env.render("index.html", ())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[actix_web::get("/actions")]
|
#[actix_web::get("/actions")]
|
||||||
pub async fn actions(tmpl_env: MiniJinjaRenderer) -> actix_web::Result<impl Responder> {
|
pub async fn actions(tmpl_env: MiniJinjaRenderer) -> actix_web::Result<impl Responder> {
|
||||||
tmpl_env.render("actions.html", ())
|
tmpl_env.render("actions.html", ())
|
||||||
@@ -37,32 +32,6 @@ pub async fn overview(
|
|||||||
tmpl_env.render("overview.html", ctx)
|
tmpl_env.render("overview.html", ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
|
||||||
struct LoginPayload {
|
|
||||||
username: String,
|
|
||||||
password: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[actix_web::post("/login")]
|
|
||||||
pub async fn login(
|
|
||||||
tmpl_env: MiniJinjaRenderer,
|
|
||||||
web::Json(form): web::Json<LoginPayload>,
|
|
||||||
) -> actix_web::Result<impl Responder> {
|
|
||||||
let ctx = context! {
|
|
||||||
name => form.username,
|
|
||||||
};
|
|
||||||
tmpl_env.render("partials/index/success.html", ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[actix_web::post("/logout")]
|
|
||||||
pub async fn logout(tmpl_env: MiniJinjaRenderer) -> actix_web::Result<impl Responder> {
|
|
||||||
let ctx = context! {};
|
|
||||||
let res = tmpl_env.render("partials/index/form.html", ctx)?;
|
|
||||||
Ok(res
|
|
||||||
.customize()
|
|
||||||
.insert_header(("Set-Cookie", "username=nobody")))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[actix_web::get("/partials/overview/submit_button")]
|
#[actix_web::get("/partials/overview/submit_button")]
|
||||||
pub async fn overview_submit_button(
|
pub async fn overview_submit_button(
|
||||||
_req: HttpRequest,
|
_req: HttpRequest,
|
||||||
|
|||||||
Reference in new issue
Block a user