Files
2026-10-20 11:20:55 -05:00

7.4 KiB

Code Submission

This project is a Leptos + Axum app for a multi-step code submission challenge. It exposes a small web UI where users enter a code, accepts challenge submissions for valid codes, and can toggle the server between offline and live mode for SMS-driven challenge flow testing.

Overview

The app supports:

  • A home page for entering challenge codes.
  • A /submit/:code route that validates supported codes.
  • A /manage page to toggle the server between live and offline states.
  • A /history page for successful submission records.
  • A protected POST /event/buzz endpoint for challenge code 1, which validates a secret and timing window.
  • TextBee SMS notifications when the server is live.

This repository is not a generic template anymore; it is a working challenge server with specific code-handling behavior and operational configuration.

Project structure

.
├── Cargo.toml
├── README.md
├── dev.env
├── LICENSE
├── end2end/
│   ├── package.json
│   ├── playwright.config.ts
│   └── tests/
├── public/
│   ├── challenge3.txt
│   ├── challenge3_annotated.txt
│   └── favicon.ico
├── src/
│   ├── app.rs
│   ├── lib.rs
│   ├── main.rs
│   ├── manage.rs
│   ├── secrets.rs
│   └── codes/
│       ├── code1.rs
│       ├── code2.rs
│       ├── code5.rs
│       ├── history.rs
│       └── mod.rs
├── style/
│   └── main.scss
└── target/

Features

Code 1

Code 1 is the timed buzz challenge. It accepts a POST /event/buzz request with:

{
  "delay_ms": 6388,
  "secret": "<your CODE1_SECRET value>"
}

Behavior:

  • delay_ms must be a non-negative integer.
  • secret must match CODE1_SECRET exactly.
  • The request is only accepted in the America/Chicago window from 11:00 AM to 1:30 PM inclusive.
  • The server computes the signed delta from the target of 6430 ms.
  • Deltas outside the inclusive range -500 to +500 are rejected and ignored.
  • Valid submissions return HTTP 202.
  • When live, the app sends SMS notifications via TextBee to the configured recipients.
  • When offline, it logs the planned SMS actions instead.

The challenge text includes the literal strings CHALLENGE_1_FIRST and CHALLENGE_1_SECOND, which are sent to the configured recipients once the buzz is accepted.

Code 2

The code value is QJ4EAN and is case-insensitive.

On successful submission:

  • It records the success in the submission history.
  • If the server is live, it sends a TextBee SMS to RECIPIENT_SELF.
  • If the server is offline, it logs the notification instead.

Code 5

The code value is V7MK2P and is case-insensitive.

On successful submission:

  • It records the success in the submission history.
  • If the server is live, it sends a TextBee SMS to RECIPIENT_SELF.
  • If the server is offline, it logs the notification instead.
  • It shows a completion message without providing a download.

Getting started

Prerequisites

You need Rust, the Leptos toolchain, and the project dependencies.

If you do not have cargo-leptos installed:

cargo install cargo-leptos --locked

If you need the additional tooling required by cargo-leptos:

rustup toolchain install nightly --allow-downgrade
rustup target add wasm32-unknown-unknown
cargo install cargo-generate
npm install -g sass

Then install the end-to-end test dependencies:

cd end2end
npm install

Environment configuration

Copy the sample environment file to .env before starting the app:

Copy-Item dev.env .env

The app loads .env automatically at startup and validates the required values. The expected settings are defined in src/secrets.rs and include:

  • DEV_SECRET_KEY — required for admin actions such as toggling live/offline mode and accessing submission history.
  • TEXTBEE_API_KEY — required for sending SMS via TextBee.
  • TEXTBEE_DEVICE_ID — optional, selects a specific paired device.
  • RECIPIENT_SELF, RECIPIENT_1, RECIPIENT_2 — each must be a valid E.164 phone number.
  • CODE1_SECRET — required and must be at least 32 bytes long.
  • PROD — set to true to start the server in the live state. Truthy values are 1, true, yes, and on (case-insensitive); any other value starts the server offline.

Do not commit secrets or expose them in client-side code.

Run the app

cargo leptos watch

Then open the local app in your browser as directed by cargo-leptos.

Management and admin flow

The app includes a status management page at /manage.

  • It shows whether the server is currently live.
  • It lets an operator toggle the server status.
  • It requires the configured DEV_SECRET_KEY before changing state.

This is how the system can be transitioned between testing/offline and live challenge operation without exposing the settings publicly.

Challenge testing

Test Code 1 with curl

With the server running locally and CODE1_SECRET set in your shell:

curl.exe -X POST http://127.0.0.1:3000/event/buzz -H "Content-Type: application/json" -d '{"delay_ms":6388,"secret":"<your CODE1_SECRET value>"}'

The server calculates 6388 - 6430 = -42 ms, and a valid request returns HTTP 202.

Test Code 1 with Postman

Create a POST request to http://127.0.0.1:3000/event/buzz, select Body > raw > JSON, and send:

{
  "delay_ms": 6388,
  "secret": "<your CODE1_SECRET value>"
}

Test Code 1 with Node.js

async function main() {
  const delayMs = 6388;
  const secret = process.env.CODE1_SECRET;
  if (!secret) throw new Error("CODE1_SECRET is not set");

  const response = await fetch("http://127.0.0.1:3000/event/buzz", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ delay_ms: delayMs, secret }),
  });

  console.log(response.status, await response.text());
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

When the server is live, a successful test event sends the configured TextBee SMS to the configured recipients. When it is offline, it logs the action instead.

Build, test, and release

Compile for release

cargo leptos build --release

This will generate the server binary in target/release and the site bundle in target/site.

End-to-end tests

cargo leptos end-to-end
cargo leptos end-to-end --release

Cargo-leptos uses Playwright for browser tests and the test files are under end2end/tests.

Remote deployment without the Rust toolchain

After running cargo leptos build --release, the minimum files needed are:

  1. The server binary in target/server/release
  2. The site directory and all files inside it in target/site

Copy these files to your remote server. The expected directory structure is:

code_submission
site/

Set the appropriate environment variables before starting the binary:

export LEPTOS_OUTPUT_NAME="code_submission"
export LEPTOS_SITE_ROOT="site"
export LEPTOS_SITE_PKG_DIR="pkg"
export LEPTOS_SITE_ADDR="0.0.0.0:3000"
export LEPTOS_RELOAD_PORT="3001"

Then run the server binary.

Licensing

This project is released under the repository's existing license. The default template license is present in LICENSE, and you should replace it with an appropriate license if you intend to distribute this project publicly.