diff options
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Cargo.lock | 420 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | README.md | 12 | ||||
| -rw-r--r-- | src/main.rs | 12 | ||||
| -rw-r--r-- | src/routes/auth.rs | 2 | ||||
| -rw-r--r-- | static/index.html | 54 | ||||
| -rw-r--r-- | static/main.js | 42 |
8 files changed, 497 insertions, 50 deletions
@@ -1,3 +1,4 @@ /target -*.pem
\ No newline at end of file +*.pem +.env
\ No newline at end of file @@ -85,6 +85,12 @@ dependencies = [ ] [[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -175,6 +181,12 @@ dependencies = [ ] [[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] name = "cpufeatures" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -193,6 +205,18 @@ dependencies = [ ] [[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] name = "crypto-common" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -203,6 +227,44 @@ dependencies = [ ] [[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] name = "deranged" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -218,11 +280,71 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] [[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -241,6 +363,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] name = "find-msvc-tools" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -314,6 +452,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -342,6 +481,17 @@ dependencies = [ ] [[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -381,6 +531,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] name = "http" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -509,16 +677,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1" dependencies = [ "base64", + "ed25519-dalek", "getrandom 0.2.17", + "hmac", "js-sys", + "p256", + "p384", "pem", + "rand 0.8.6", + "rsa", "serde", "serde_json", + "sha2", "signature", "simple_asn1", ] [[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] name = "leb128fmt" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -531,6 +715,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] name = "libsqlite3-sys" version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -605,6 +795,22 @@ dependencies = [ ] [[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.6", + "smallvec", + "zeroize", +] + +[[package]] name = "num-conv" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -620,12 +826,24 @@ dependencies = [ ] [[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] name = "num-traits" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -635,6 +853,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] name = "parking_lot" version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -679,6 +921,15 @@ dependencies = [ ] [[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] name = "percent-encoding" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -691,6 +942,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] name = "pkg-config" version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -703,6 +975,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] name = "prettyplease" version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -713,6 +994,15 @@ dependencies = [ ] [[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] name = "proc-macro2" version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -760,6 +1050,17 @@ dependencies = [ [[package]] name = "rand" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" @@ -770,6 +1071,16 @@ dependencies = [ ] [[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -794,6 +1105,36 @@ dependencies = [ ] [[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rsa" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] name = "rsqlite-vfs" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -819,6 +1160,15 @@ dependencies = [ ] [[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -846,6 +1196,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] name = "semver" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -918,6 +1282,17 @@ dependencies = [ ] [[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest", +] + +[[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -929,6 +1304,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ + "digest", "rand_core 0.6.4", ] @@ -967,6 +1343,22 @@ dependencies = [ ] [[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] name = "sqlite-wasm-rs" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1196,7 +1588,7 @@ checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ "getrandom 0.4.2", "js-sys", - "rand", + "rand 0.10.1", "wasm-bindgen", ] @@ -1425,6 +1817,32 @@ dependencies = [ ] [[package]] +name = "zerocopy" +version = "0.8.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6,7 +6,7 @@ edition = "2024" [dependencies] argon2 = { version = "0.5.3", features = ["std"] } axum = "0.8.9" -jsonwebtoken = "10.3.0" +jsonwebtoken = { version = "10.3.0", features = ["rust_crypto"] } r2d2 = "0.8.10" r2d2_sqlite = "0.34.0" serde = { version = "1.0.228", features = ["derive"] } diff --git a/README.md b/README.md new file mode 100644 index 0000000..f2f34a1 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Campersand Code Golf Leaderboard + +A simple web app for keeping track of camper code golf submissions + +## Running + +The app expects an environment variable JWT_SECRET to hold a secret for encrypting JWTs. +If you have your secret in `.env` you can run the server like this + +```bash +env $(cat .env | xargs) cargo run +```
\ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 4daba48..511a8f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ use axum::{ use jsonwebtoken::EncodingKey; use routes::problem::{get_problems, create_problem}; use routes::user::create_user; +use routes::auth::login; use tower_http::services::ServeDir; use crate::database::Database; @@ -25,15 +26,13 @@ struct AppState { #[tokio::main] async fn main() { - let Ok(api_key_string) = fs::read_to_string("api-key.pem") else { - eprintln!("failed to read api-key.pem"); + let Ok(secret) = env::var("JWT_SECRET") else { + eprintln!("missing environment variable JWT_SECRET"); return; }; - let Ok(api_key) = EncodingKey::from_ec_pem(api_key_string.as_bytes()) else { - eprintln!("failed to decode key from api-key.pem"); - return; - }; + let api_key = EncodingKey::from_secret(secret.as_ref()); + let database = Database::new_in_memory().unwrap(); database.initialize().unwrap(); @@ -49,6 +48,7 @@ async fn main() { .route("/problem", get(get_problems)) .route("/problem", post(create_problem)) .route("/user", post(create_user)) + .route("/login", post(login)) .nest_service("/static", static_files) .with_state(state); diff --git a/src/routes/auth.rs b/src/routes/auth.rs index 0b17ef4..64ada2b 100644 --- a/src/routes/auth.rs +++ b/src/routes/auth.rs @@ -58,7 +58,7 @@ pub async fn login( }; let token= encode(&Header::default(), &claims, &state.api_key) - .map_err(|_| RouteError::Internal("failed to encode jwt".into()))?; + .map_err(|e| RouteError::Internal(format!("failed to encode jwt: {e}")))?; Ok(Json(LoginResponse { token })) } diff --git a/static/index.html b/static/index.html index 69c19a5..061ca11 100644 --- a/static/index.html +++ b/static/index.html @@ -4,64 +4,38 @@ <head> <meta charset="utf-8" /> <title>Code Golf Leaderboard</title> - <link rel="stylesheet" href="default.css"/> - <script type="text/javascript"> - async function fetch_problems() { - const response = await fetch("/problem"); - if (!response.ok) { - console.log("ummm"); - } - - const result = await response.json(); - console.log(result); - - const problems_div = document.getElementById("problems"); - while (problems_div.firstChild) { - problems_div.removeChild(problems_div.lastChild); - } - - for (const problem of result) { - const problem_div = document.createElement("div"); - problem_div.className = "problem"; - problems_div.appendChild(problem_div); - - const title = document.createElement("h2"); - title.innerHTML = problem.title; - problem_div.appendChild(title); - - const description = document.createElement("p"); - description.innerHTML = problem.description; - problem_div.appendChild(description); - } - } - - async function on_load() { - const login_anchor = document.createElement("a"); - login_anchor.innerText = "Login / Register"; - login_anchor.href="google.com"; - document.getElementById("login-notice").appendChild(login_anchor); - - } - </script> + <link rel="stylesheet" href="default.css"> + <script type="text/javascript" src="main.js"></script> </head> <body onload="on_load()"> <div id="layout"> <div id="container"> <div id="content"> + <form id="login-form"> + <label for="login-email">Email</label> + <input type="text" id="login-email" name="login-email"> + <br> + <label for="login-password">Password</label> + <input type="password" id="login-password" name="login-password"> + <br> + <input type="submit" value="Login"> + </form> <span id="login-notice"></span> <h1>C&! Code Golf Leaderboard</h1> <p>In golf, the goal is to get a ball into a hole in as few swings as possible. The goal of code golf is similarly to solve a problem in as few bytes (of source code) as possible. The following is a list of programming challenges. Your task is to try and solve them in Python with as little code as possible measured in bytes.</p> - <button onclick="fetch_problems()">Refresh Problems</button> + <div id="problems"> <div class="problem"> <h2>Title</h2> <p>Description</p> </div> </div> + + <button onclick="fetch_problems()">Refresh Problems</button> <center>© 2026 Daniel Hader</center> </div> diff --git a/static/main.js b/static/main.js new file mode 100644 index 0000000..e0c0b3e --- /dev/null +++ b/static/main.js @@ -0,0 +1,42 @@ +async function login() { + +} + +async function fetch_problems() { + const response = await fetch("/problem"); + if (!response.ok) { + console.log("ummm"); + } + + const result = await response.json(); + console.log(result); + + const problems_div = document.getElementById("problems"); + while (problems_div.firstChild) { + problems_div.removeChild(problems_div.lastChild); + } + + for (const problem of result) { + const problem_div = document.createElement("div"); + problem_div.className = "problem"; + problems_div.appendChild(problem_div); + + const title = document.createElement("h2"); + title.innerHTML = problem.title; + problem_div.appendChild(title); + + const description = document.createElement("p"); + description.innerHTML = problem.description; + problem_div.appendChild(description); + } +} + +async function on_load() { + await fetch_problems(); + + const login_anchor = document.createElement("a"); + login_anchor.innerText = "Login / Register"; + login_anchor.href="google.com"; + document.getElementById("login-notice").appendChild(login_anchor); + +} |
