Code1 now only submits within the correct time window
This commit is contained in:
+5
-1
@@ -10,6 +10,8 @@ crate-type = ["cdylib", "rlib"]
|
|||||||
leptos = { version = "0.8.0" }
|
leptos = { version = "0.8.0" }
|
||||||
leptos_router = { version = "0.8.0" }
|
leptos_router = { version = "0.8.0" }
|
||||||
axum = { version = "0.8.0", optional = true }
|
axum = { version = "0.8.0", optional = true }
|
||||||
|
chrono = { version = "0.4", default-features = false, features = ["clock"], optional = true }
|
||||||
|
chrono-tz = { version = "0.10", optional = true }
|
||||||
console_error_panic_hook = { version = "0.1", optional = true }
|
console_error_panic_hook = { version = "0.1", optional = true }
|
||||||
dotenvy = { version = "0.15", optional = true }
|
dotenvy = { version = "0.15", optional = true }
|
||||||
leptos_axum = { version = "0.8.0", optional = true }
|
leptos_axum = { version = "0.8.0", optional = true }
|
||||||
@@ -28,6 +30,8 @@ hydrate = [
|
|||||||
]
|
]
|
||||||
ssr = [
|
ssr = [
|
||||||
"dep:axum",
|
"dep:axum",
|
||||||
|
"dep:chrono",
|
||||||
|
"dep:chrono-tz",
|
||||||
"dep:dotenvy",
|
"dep:dotenvy",
|
||||||
"dep:tokio",
|
"dep:tokio",
|
||||||
"dep:leptos_axum",
|
"dep:leptos_axum",
|
||||||
@@ -66,7 +70,7 @@ style-file = "style/main.scss"
|
|||||||
assets-dir = "public"
|
assets-dir = "public"
|
||||||
|
|
||||||
# The IP and port (ex: 127.0.0.1:3000) where the server serves the content. Use it in your server setup.
|
# The IP and port (ex: 127.0.0.1:3000) where the server serves the content. Use it in your server setup.
|
||||||
site-addr = "127.0.0.1:3000"
|
site-addr = "0.0.0.0:3000"
|
||||||
|
|
||||||
# The port to use for automatic reload monitoring
|
# The port to use for automatic reload monitoring
|
||||||
reload-port = 3001
|
reload-port = 3001
|
||||||
|
|||||||
@@ -71,7 +71,12 @@ step when ready.
|
|||||||
The robot submits code 1 with `POST /event/buzz` and a JSON body containing
|
The robot submits code 1 with `POST /event/buzz` and a JSON body containing
|
||||||
`delay_ms` (a non-negative integer) and `secret` (the value of `CODE1_SECRET`).
|
`delay_ms` (a non-negative integer) and `secret` (the value of `CODE1_SECRET`).
|
||||||
The server subtracts the target delay of 6430 ms from `delay_ms` to calculate
|
The server subtracts the target delay of 6430 ms from `delay_ms` to calculate
|
||||||
the signed buzz delta.
|
the signed buzz delta. Deltas outside the inclusive range -500 to +500 ms are
|
||||||
|
logged and ignored; the endpoint returns HTTP `200` and does not record the
|
||||||
|
submission or send/log the submission actions. Accepted submissions return
|
||||||
|
HTTP `202`. Correctly timed buzzes are only accepted between 11:00 AM and
|
||||||
|
1:30 PM, inclusive, in the `America/Chicago` timezone. Requests outside that
|
||||||
|
window are logged and return HTTP `200` without running submission actions.
|
||||||
Set `CODE1_SECRET` to a unique random secret of at least 32 bytes in
|
Set `CODE1_SECRET` to a unique random secret of at least 32 bytes in
|
||||||
`.env`. For example, with the server running locally:
|
`.env`. For example, with the server running locally:
|
||||||
|
|
||||||
@@ -167,7 +172,7 @@ Set the following environment variables (updating for your project as needed):
|
|||||||
export LEPTOS_OUTPUT_NAME="code_submission"
|
export LEPTOS_OUTPUT_NAME="code_submission"
|
||||||
export LEPTOS_SITE_ROOT="site"
|
export LEPTOS_SITE_ROOT="site"
|
||||||
export LEPTOS_SITE_PKG_DIR="pkg"
|
export LEPTOS_SITE_PKG_DIR="pkg"
|
||||||
export LEPTOS_SITE_ADDR="127.0.0.1:3000"
|
export LEPTOS_SITE_ADDR="0.0.0.0:3000"
|
||||||
export LEPTOS_RELOAD_PORT="3001"
|
export LEPTOS_RELOAD_PORT="3001"
|
||||||
```
|
```
|
||||||
Finally, run the server binary.
|
Finally, run the server binary.
|
||||||
|
|||||||
+27
-1
@@ -1,9 +1,13 @@
|
|||||||
use axum::{extract::ConnectInfo, http::StatusCode, Json};
|
use axum::{extract::ConnectInfo, http::StatusCode, Json};
|
||||||
|
use chrono::Timelike;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
pub const ID: &str = "code1";
|
pub const ID: &str = "code1";
|
||||||
const TARGET_DELAY_MS: i64 = 6430;
|
const TARGET_DELAY_MS: i64 = 6430;
|
||||||
|
const MAX_BUZZ_DELTA_MS: i64 = 500;
|
||||||
|
const ACCEPTANCE_START_SECONDS: u32 = 11 * 60 * 60;
|
||||||
|
const ACCEPTANCE_END_SECONDS: u32 = 13 * 60 * 60 + 30 * 60;
|
||||||
const SELF_NOTIFICATION: &str = "Code 1 has been submitted while the server is live.";
|
const SELF_NOTIFICATION: &str = "Code 1 has been submitted while the server is live.";
|
||||||
const CHALLENGE_1_FIRST: &str = "SECDED-13\nPARITY MSB...LSB";
|
const CHALLENGE_1_FIRST: &str = "SECDED-13\nPARITY MSB...LSB";
|
||||||
const CHALLENGE_1_SECOND: &str = "0x144A
|
const CHALLENGE_1_SECOND: &str = "0x144A
|
||||||
@@ -77,10 +81,32 @@ pub async fn buzz_event_handler(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let chicago_now = chrono::Utc::now().with_timezone(&chrono_tz::America::Chicago);
|
||||||
|
let seconds_since_midnight = chicago_now.num_seconds_from_midnight();
|
||||||
|
let after_start = seconds_since_midnight >= ACCEPTANCE_START_SECONDS;
|
||||||
|
let before_or_at_end = seconds_since_midnight < ACCEPTANCE_END_SECONDS
|
||||||
|
|| (seconds_since_midnight == ACCEPTANCE_END_SECONDS && chicago_now.nanosecond() == 0);
|
||||||
|
if !after_start || !before_or_at_end {
|
||||||
|
leptos::logging::log!(
|
||||||
|
"Code 1 buzz rejected outside acceptance window: local_time={}, source={}",
|
||||||
|
chicago_now.format("%Y-%m-%d %H:%M:%S %Z"),
|
||||||
|
address.ip()
|
||||||
|
);
|
||||||
|
return Ok(StatusCode::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
let delta_ms = delay_ms - TARGET_DELAY_MS;
|
||||||
|
if delta_ms.abs() > MAX_BUZZ_DELTA_MS {
|
||||||
|
leptos::logging::log!(
|
||||||
|
"Code 1 buzz rejected: delay_ms={delay_ms}, delta_ms={delta_ms}, source={}",
|
||||||
|
address.ip()
|
||||||
|
);
|
||||||
|
return Ok(StatusCode::OK);
|
||||||
|
}
|
||||||
|
|
||||||
let live = crate::manage::server_live_state();
|
let live = crate::manage::server_live_state();
|
||||||
crate::codes::history::record_successful_submission(address.ip(), live, ID)
|
crate::codes::history::record_successful_submission(address.ip(), live, ID)
|
||||||
.map_err(|error| (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()))?;
|
.map_err(|error| (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()))?;
|
||||||
let delta_ms = delay_ms - TARGET_DELAY_MS;
|
|
||||||
on_submit(live, delta_ms).await.map_err(|error| {
|
on_submit(live, delta_ms).await.map_err(|error| {
|
||||||
leptos::logging::log!("Code 1 buzz event failed: {error}");
|
leptos::logging::log!("Code 1 buzz event failed: {error}");
|
||||||
(
|
(
|
||||||
|
|||||||
Reference in New Issue
Block a user