├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── FullScreenCapture.png ├── LICENSE ├── MobileScreenCapture.png ├── README.md ├── back_end ├── Cargo.toml └── src │ ├── main.rs │ ├── middlewares.rs │ ├── middlewares │ ├── authenticator.rs │ └── usersecure.rs │ ├── routes.rs │ ├── routes │ ├── api.rs │ ├── auth.rs │ ├── notimplemented.rs │ └── session.rs │ ├── services.rs │ └── store.rs ├── build-fullstack.sh ├── common ├── Cargo.toml └── src │ └── lib.rs └── front_end ├── index.html ├── jsconfig.json ├── package.json ├── public ├── favicon.ico └── global.css ├── src ├── App.svelte ├── app.css ├── component │ └── Navbar.svelte ├── js │ ├── auth.js │ ├── fetch.js │ └── store.js ├── main.js ├── pages │ ├── Apicheck.svelte │ ├── Login.svelte │ ├── Logout.svelte │ └── Secure.svelte └── vite-env.d.ts ├── svelte.config.js └── vite.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor directories and files 2 | .vscode/* 3 | 4 | # from rust 5 | Cargo.lock 6 | /target 7 | 8 | # from svelte 9 | /front_end/node_modules 10 | /front_end/dist/ 11 | /front_end/package-lock.json -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.20.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.0.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "alloc-no-stdlib" 31 | version = "2.0.4" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" 34 | 35 | [[package]] 36 | name = "alloc-stdlib" 37 | version = "0.2.2" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" 40 | dependencies = [ 41 | "alloc-no-stdlib", 42 | ] 43 | 44 | [[package]] 45 | name = "async-compression" 46 | version = "0.4.1" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "62b74f44609f0f91493e3082d3734d98497e094777144380ea4db9f9905dd5b6" 49 | dependencies = [ 50 | "brotli", 51 | "flate2", 52 | "futures-core", 53 | "memchr", 54 | "pin-project-lite", 55 | "tokio", 56 | "zstd", 57 | "zstd-safe", 58 | ] 59 | 60 | [[package]] 61 | name = "async-trait" 62 | version = "0.1.73" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" 65 | dependencies = [ 66 | "proc-macro2", 67 | "quote", 68 | "syn", 69 | ] 70 | 71 | [[package]] 72 | name = "autocfg" 73 | version = "1.1.0" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 76 | 77 | [[package]] 78 | name = "axum" 79 | version = "0.6.20" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" 82 | dependencies = [ 83 | "async-trait", 84 | "axum-core", 85 | "bitflags 1.3.2", 86 | "bytes", 87 | "futures-util", 88 | "headers", 89 | "http", 90 | "http-body", 91 | "hyper", 92 | "itoa", 93 | "matchit", 94 | "memchr", 95 | "mime", 96 | "percent-encoding", 97 | "pin-project-lite", 98 | "rustversion", 99 | "serde", 100 | "serde_json", 101 | "serde_path_to_error", 102 | "serde_urlencoded", 103 | "sync_wrapper", 104 | "tokio", 105 | "tower", 106 | "tower-layer", 107 | "tower-service", 108 | ] 109 | 110 | [[package]] 111 | name = "axum-core" 112 | version = "0.3.4" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" 115 | dependencies = [ 116 | "async-trait", 117 | "bytes", 118 | "futures-util", 119 | "http", 120 | "http-body", 121 | "mime", 122 | "rustversion", 123 | "tower-layer", 124 | "tower-service", 125 | ] 126 | 127 | [[package]] 128 | name = "backtrace" 129 | version = "0.3.68" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" 132 | dependencies = [ 133 | "addr2line", 134 | "cc", 135 | "cfg-if", 136 | "libc", 137 | "miniz_oxide", 138 | "object", 139 | "rustc-demangle", 140 | ] 141 | 142 | [[package]] 143 | name = "base64" 144 | version = "0.13.1" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 147 | 148 | [[package]] 149 | name = "base64" 150 | version = "0.21.2" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" 153 | 154 | [[package]] 155 | name = "bitflags" 156 | version = "1.3.2" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 159 | 160 | [[package]] 161 | name = "bitflags" 162 | version = "2.4.0" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" 165 | 166 | [[package]] 167 | name = "block-buffer" 168 | version = "0.10.4" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 171 | dependencies = [ 172 | "generic-array", 173 | ] 174 | 175 | [[package]] 176 | name = "brotli" 177 | version = "3.3.4" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" 180 | dependencies = [ 181 | "alloc-no-stdlib", 182 | "alloc-stdlib", 183 | "brotli-decompressor", 184 | ] 185 | 186 | [[package]] 187 | name = "brotli-decompressor" 188 | version = "2.3.4" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" 191 | dependencies = [ 192 | "alloc-no-stdlib", 193 | "alloc-stdlib", 194 | ] 195 | 196 | [[package]] 197 | name = "bytes" 198 | version = "1.4.0" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 201 | 202 | [[package]] 203 | name = "cc" 204 | version = "1.0.82" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" 207 | dependencies = [ 208 | "jobserver", 209 | "libc", 210 | ] 211 | 212 | [[package]] 213 | name = "cfg-if" 214 | version = "1.0.0" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 217 | 218 | [[package]] 219 | name = "common" 220 | version = "0.1.0" 221 | 222 | [[package]] 223 | name = "cookie" 224 | version = "0.17.0" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" 227 | dependencies = [ 228 | "percent-encoding", 229 | "time", 230 | "version_check", 231 | ] 232 | 233 | [[package]] 234 | name = "cpufeatures" 235 | version = "0.2.9" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" 238 | dependencies = [ 239 | "libc", 240 | ] 241 | 242 | [[package]] 243 | name = "crc32fast" 244 | version = "1.3.2" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 247 | dependencies = [ 248 | "cfg-if", 249 | ] 250 | 251 | [[package]] 252 | name = "crypto-common" 253 | version = "0.1.6" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 256 | dependencies = [ 257 | "generic-array", 258 | "typenum", 259 | ] 260 | 261 | [[package]] 262 | name = "deranged" 263 | version = "0.3.7" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" 266 | dependencies = [ 267 | "serde", 268 | ] 269 | 270 | [[package]] 271 | name = "digest" 272 | version = "0.10.7" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 275 | dependencies = [ 276 | "block-buffer", 277 | "crypto-common", 278 | ] 279 | 280 | [[package]] 281 | name = "flate2" 282 | version = "1.0.26" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" 285 | dependencies = [ 286 | "crc32fast", 287 | "miniz_oxide", 288 | ] 289 | 290 | [[package]] 291 | name = "fnv" 292 | version = "1.0.7" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 295 | 296 | [[package]] 297 | name = "form_urlencoded" 298 | version = "1.2.0" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 301 | dependencies = [ 302 | "percent-encoding", 303 | ] 304 | 305 | [[package]] 306 | name = "futures" 307 | version = "0.3.28" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" 310 | dependencies = [ 311 | "futures-channel", 312 | "futures-core", 313 | "futures-io", 314 | "futures-sink", 315 | "futures-task", 316 | "futures-util", 317 | ] 318 | 319 | [[package]] 320 | name = "futures-channel" 321 | version = "0.3.28" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 324 | dependencies = [ 325 | "futures-core", 326 | "futures-sink", 327 | ] 328 | 329 | [[package]] 330 | name = "futures-core" 331 | version = "0.3.28" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 334 | 335 | [[package]] 336 | name = "futures-io" 337 | version = "0.3.28" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 340 | 341 | [[package]] 342 | name = "futures-macro" 343 | version = "0.3.28" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" 346 | dependencies = [ 347 | "proc-macro2", 348 | "quote", 349 | "syn", 350 | ] 351 | 352 | [[package]] 353 | name = "futures-sink" 354 | version = "0.3.28" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 357 | 358 | [[package]] 359 | name = "futures-task" 360 | version = "0.3.28" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 363 | 364 | [[package]] 365 | name = "futures-util" 366 | version = "0.3.28" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 369 | dependencies = [ 370 | "futures-core", 371 | "futures-macro", 372 | "futures-sink", 373 | "futures-task", 374 | "pin-project-lite", 375 | "pin-utils", 376 | "slab", 377 | ] 378 | 379 | [[package]] 380 | name = "generic-array" 381 | version = "0.14.7" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 384 | dependencies = [ 385 | "typenum", 386 | "version_check", 387 | ] 388 | 389 | [[package]] 390 | name = "getrandom" 391 | version = "0.2.10" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 394 | dependencies = [ 395 | "cfg-if", 396 | "libc", 397 | "wasi", 398 | ] 399 | 400 | [[package]] 401 | name = "gimli" 402 | version = "0.27.3" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" 405 | 406 | [[package]] 407 | name = "headers" 408 | version = "0.3.8" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" 411 | dependencies = [ 412 | "base64 0.13.1", 413 | "bitflags 1.3.2", 414 | "bytes", 415 | "headers-core", 416 | "http", 417 | "httpdate", 418 | "mime", 419 | "sha1", 420 | ] 421 | 422 | [[package]] 423 | name = "headers-core" 424 | version = "0.2.0" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" 427 | dependencies = [ 428 | "http", 429 | ] 430 | 431 | [[package]] 432 | name = "hermit-abi" 433 | version = "0.3.2" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" 436 | 437 | [[package]] 438 | name = "http" 439 | version = "0.2.9" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 442 | dependencies = [ 443 | "bytes", 444 | "fnv", 445 | "itoa", 446 | ] 447 | 448 | [[package]] 449 | name = "http-body" 450 | version = "0.4.5" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 453 | dependencies = [ 454 | "bytes", 455 | "http", 456 | "pin-project-lite", 457 | ] 458 | 459 | [[package]] 460 | name = "http-range-header" 461 | version = "0.3.1" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" 464 | 465 | [[package]] 466 | name = "httparse" 467 | version = "1.8.0" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 470 | 471 | [[package]] 472 | name = "httpdate" 473 | version = "1.0.2" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 476 | 477 | [[package]] 478 | name = "hyper" 479 | version = "0.14.27" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" 482 | dependencies = [ 483 | "bytes", 484 | "futures-channel", 485 | "futures-core", 486 | "futures-util", 487 | "http", 488 | "http-body", 489 | "httparse", 490 | "httpdate", 491 | "itoa", 492 | "pin-project-lite", 493 | "socket2 0.4.9", 494 | "tokio", 495 | "tower-service", 496 | "tracing", 497 | "want", 498 | ] 499 | 500 | [[package]] 501 | name = "iri-string" 502 | version = "0.7.0" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "21859b667d66a4c1dacd9df0863b3efb65785474255face87f5bca39dd8407c0" 505 | dependencies = [ 506 | "memchr", 507 | "serde", 508 | ] 509 | 510 | [[package]] 511 | name = "itoa" 512 | version = "1.0.9" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" 515 | 516 | [[package]] 517 | name = "jobserver" 518 | version = "0.1.26" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" 521 | dependencies = [ 522 | "libc", 523 | ] 524 | 525 | [[package]] 526 | name = "lazy_static" 527 | version = "1.4.0" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 530 | 531 | [[package]] 532 | name = "libc" 533 | version = "0.2.147" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" 536 | 537 | [[package]] 538 | name = "lock_api" 539 | version = "0.4.10" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" 542 | dependencies = [ 543 | "autocfg", 544 | "scopeguard", 545 | "serde", 546 | ] 547 | 548 | [[package]] 549 | name = "log" 550 | version = "0.4.19" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" 553 | 554 | [[package]] 555 | name = "matchers" 556 | version = "0.1.0" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 559 | dependencies = [ 560 | "regex-automata 0.1.10", 561 | ] 562 | 563 | [[package]] 564 | name = "matchit" 565 | version = "0.7.2" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" 568 | 569 | [[package]] 570 | name = "memchr" 571 | version = "2.5.0" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 574 | 575 | [[package]] 576 | name = "mime" 577 | version = "0.3.17" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 580 | 581 | [[package]] 582 | name = "mime_guess" 583 | version = "2.0.4" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" 586 | dependencies = [ 587 | "mime", 588 | "unicase", 589 | ] 590 | 591 | [[package]] 592 | name = "miniz_oxide" 593 | version = "0.7.1" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 596 | dependencies = [ 597 | "adler", 598 | ] 599 | 600 | [[package]] 601 | name = "mio" 602 | version = "0.8.8" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" 605 | dependencies = [ 606 | "libc", 607 | "wasi", 608 | "windows-sys", 609 | ] 610 | 611 | [[package]] 612 | name = "nu-ansi-term" 613 | version = "0.46.0" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 616 | dependencies = [ 617 | "overload", 618 | "winapi", 619 | ] 620 | 621 | [[package]] 622 | name = "num_cpus" 623 | version = "1.16.0" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 626 | dependencies = [ 627 | "hermit-abi", 628 | "libc", 629 | ] 630 | 631 | [[package]] 632 | name = "object" 633 | version = "0.31.1" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" 636 | dependencies = [ 637 | "memchr", 638 | ] 639 | 640 | [[package]] 641 | name = "once_cell" 642 | version = "1.18.0" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 645 | 646 | [[package]] 647 | name = "overload" 648 | version = "0.1.1" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 651 | 652 | [[package]] 653 | name = "parking_lot" 654 | version = "0.12.1" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 657 | dependencies = [ 658 | "lock_api", 659 | "parking_lot_core", 660 | ] 661 | 662 | [[package]] 663 | name = "parking_lot_core" 664 | version = "0.9.8" 665 | source = "registry+https://github.com/rust-lang/crates.io-index" 666 | checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" 667 | dependencies = [ 668 | "cfg-if", 669 | "libc", 670 | "redox_syscall", 671 | "smallvec", 672 | "windows-targets", 673 | ] 674 | 675 | [[package]] 676 | name = "percent-encoding" 677 | version = "2.3.0" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 680 | 681 | [[package]] 682 | name = "pin-project" 683 | version = "1.1.3" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" 686 | dependencies = [ 687 | "pin-project-internal", 688 | ] 689 | 690 | [[package]] 691 | name = "pin-project-internal" 692 | version = "1.1.3" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" 695 | dependencies = [ 696 | "proc-macro2", 697 | "quote", 698 | "syn", 699 | ] 700 | 701 | [[package]] 702 | name = "pin-project-lite" 703 | version = "0.2.12" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" 706 | 707 | [[package]] 708 | name = "pin-utils" 709 | version = "0.1.0" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 712 | 713 | [[package]] 714 | name = "pkg-config" 715 | version = "0.3.27" 716 | source = "registry+https://github.com/rust-lang/crates.io-index" 717 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" 718 | 719 | [[package]] 720 | name = "proc-macro2" 721 | version = "1.0.66" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" 724 | dependencies = [ 725 | "unicode-ident", 726 | ] 727 | 728 | [[package]] 729 | name = "quote" 730 | version = "1.0.32" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" 733 | dependencies = [ 734 | "proc-macro2", 735 | ] 736 | 737 | [[package]] 738 | name = "redox_syscall" 739 | version = "0.3.5" 740 | source = "registry+https://github.com/rust-lang/crates.io-index" 741 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 742 | dependencies = [ 743 | "bitflags 1.3.2", 744 | ] 745 | 746 | [[package]] 747 | name = "regex" 748 | version = "1.9.3" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" 751 | dependencies = [ 752 | "aho-corasick", 753 | "memchr", 754 | "regex-automata 0.3.6", 755 | "regex-syntax 0.7.4", 756 | ] 757 | 758 | [[package]] 759 | name = "regex-automata" 760 | version = "0.1.10" 761 | source = "registry+https://github.com/rust-lang/crates.io-index" 762 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 763 | dependencies = [ 764 | "regex-syntax 0.6.29", 765 | ] 766 | 767 | [[package]] 768 | name = "regex-automata" 769 | version = "0.3.6" 770 | source = "registry+https://github.com/rust-lang/crates.io-index" 771 | checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" 772 | dependencies = [ 773 | "aho-corasick", 774 | "memchr", 775 | "regex-syntax 0.7.4", 776 | ] 777 | 778 | [[package]] 779 | name = "regex-syntax" 780 | version = "0.6.29" 781 | source = "registry+https://github.com/rust-lang/crates.io-index" 782 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 783 | 784 | [[package]] 785 | name = "regex-syntax" 786 | version = "0.7.4" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" 789 | 790 | [[package]] 791 | name = "rustc-demangle" 792 | version = "0.1.23" 793 | source = "registry+https://github.com/rust-lang/crates.io-index" 794 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 795 | 796 | [[package]] 797 | name = "rustversion" 798 | version = "1.0.14" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" 801 | 802 | [[package]] 803 | name = "ryu" 804 | version = "1.0.15" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" 807 | 808 | [[package]] 809 | name = "scopeguard" 810 | version = "1.2.0" 811 | source = "registry+https://github.com/rust-lang/crates.io-index" 812 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 813 | 814 | [[package]] 815 | name = "serde" 816 | version = "1.0.188" 817 | source = "registry+https://github.com/rust-lang/crates.io-index" 818 | checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" 819 | dependencies = [ 820 | "serde_derive", 821 | ] 822 | 823 | [[package]] 824 | name = "serde_derive" 825 | version = "1.0.188" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" 828 | dependencies = [ 829 | "proc-macro2", 830 | "quote", 831 | "syn", 832 | ] 833 | 834 | [[package]] 835 | name = "serde_json" 836 | version = "1.0.107" 837 | source = "registry+https://github.com/rust-lang/crates.io-index" 838 | checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" 839 | dependencies = [ 840 | "itoa", 841 | "ryu", 842 | "serde", 843 | ] 844 | 845 | [[package]] 846 | name = "serde_path_to_error" 847 | version = "0.1.14" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" 850 | dependencies = [ 851 | "itoa", 852 | "serde", 853 | ] 854 | 855 | [[package]] 856 | name = "serde_urlencoded" 857 | version = "0.7.1" 858 | source = "registry+https://github.com/rust-lang/crates.io-index" 859 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 860 | dependencies = [ 861 | "form_urlencoded", 862 | "itoa", 863 | "ryu", 864 | "serde", 865 | ] 866 | 867 | [[package]] 868 | name = "sha1" 869 | version = "0.10.5" 870 | source = "registry+https://github.com/rust-lang/crates.io-index" 871 | checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" 872 | dependencies = [ 873 | "cfg-if", 874 | "cpufeatures", 875 | "digest", 876 | ] 877 | 878 | [[package]] 879 | name = "sharded-slab" 880 | version = "0.1.4" 881 | source = "registry+https://github.com/rust-lang/crates.io-index" 882 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 883 | dependencies = [ 884 | "lazy_static", 885 | ] 886 | 887 | [[package]] 888 | name = "signal-hook-registry" 889 | version = "1.4.1" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 892 | dependencies = [ 893 | "libc", 894 | ] 895 | 896 | [[package]] 897 | name = "slab" 898 | version = "0.4.8" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" 901 | dependencies = [ 902 | "autocfg", 903 | ] 904 | 905 | [[package]] 906 | name = "smallvec" 907 | version = "1.11.0" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" 910 | 911 | [[package]] 912 | name = "socket2" 913 | version = "0.4.9" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 916 | dependencies = [ 917 | "libc", 918 | "winapi", 919 | ] 920 | 921 | [[package]] 922 | name = "socket2" 923 | version = "0.5.3" 924 | source = "registry+https://github.com/rust-lang/crates.io-index" 925 | checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" 926 | dependencies = [ 927 | "libc", 928 | "windows-sys", 929 | ] 930 | 931 | [[package]] 932 | name = "svelte-axum-project" 933 | version = "0.4.2" 934 | dependencies = [ 935 | "axum", 936 | "serde", 937 | "serde_json", 938 | "tokio", 939 | "tower", 940 | "tower-http", 941 | "tower-sessions", 942 | "tracing", 943 | "tracing-subscriber", 944 | ] 945 | 946 | [[package]] 947 | name = "syn" 948 | version = "2.0.28" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" 951 | dependencies = [ 952 | "proc-macro2", 953 | "quote", 954 | "unicode-ident", 955 | ] 956 | 957 | [[package]] 958 | name = "sync_wrapper" 959 | version = "0.1.2" 960 | source = "registry+https://github.com/rust-lang/crates.io-index" 961 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 962 | 963 | [[package]] 964 | name = "thiserror" 965 | version = "1.0.49" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" 968 | dependencies = [ 969 | "thiserror-impl", 970 | ] 971 | 972 | [[package]] 973 | name = "thiserror-impl" 974 | version = "1.0.49" 975 | source = "registry+https://github.com/rust-lang/crates.io-index" 976 | checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" 977 | dependencies = [ 978 | "proc-macro2", 979 | "quote", 980 | "syn", 981 | ] 982 | 983 | [[package]] 984 | name = "thread_local" 985 | version = "1.1.7" 986 | source = "registry+https://github.com/rust-lang/crates.io-index" 987 | checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" 988 | dependencies = [ 989 | "cfg-if", 990 | "once_cell", 991 | ] 992 | 993 | [[package]] 994 | name = "time" 995 | version = "0.3.29" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe" 998 | dependencies = [ 999 | "deranged", 1000 | "itoa", 1001 | "serde", 1002 | "time-core", 1003 | "time-macros", 1004 | ] 1005 | 1006 | [[package]] 1007 | name = "time-core" 1008 | version = "0.1.2" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 1011 | 1012 | [[package]] 1013 | name = "time-macros" 1014 | version = "0.2.15" 1015 | source = "registry+https://github.com/rust-lang/crates.io-index" 1016 | checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" 1017 | dependencies = [ 1018 | "time-core", 1019 | ] 1020 | 1021 | [[package]] 1022 | name = "tokio" 1023 | version = "1.30.0" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "2d3ce25f50619af8b0aec2eb23deebe84249e19e2ddd393a6e16e3300a6dadfd" 1026 | dependencies = [ 1027 | "backtrace", 1028 | "bytes", 1029 | "libc", 1030 | "mio", 1031 | "num_cpus", 1032 | "parking_lot", 1033 | "pin-project-lite", 1034 | "signal-hook-registry", 1035 | "socket2 0.5.3", 1036 | "tokio-macros", 1037 | "windows-sys", 1038 | ] 1039 | 1040 | [[package]] 1041 | name = "tokio-macros" 1042 | version = "2.1.0" 1043 | source = "registry+https://github.com/rust-lang/crates.io-index" 1044 | checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" 1045 | dependencies = [ 1046 | "proc-macro2", 1047 | "quote", 1048 | "syn", 1049 | ] 1050 | 1051 | [[package]] 1052 | name = "tokio-util" 1053 | version = "0.7.8" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" 1056 | dependencies = [ 1057 | "bytes", 1058 | "futures-core", 1059 | "futures-sink", 1060 | "pin-project-lite", 1061 | "tokio", 1062 | ] 1063 | 1064 | [[package]] 1065 | name = "tower" 1066 | version = "0.4.13" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 1069 | dependencies = [ 1070 | "futures-core", 1071 | "futures-util", 1072 | "pin-project", 1073 | "pin-project-lite", 1074 | "tokio", 1075 | "tower-layer", 1076 | "tower-service", 1077 | "tracing", 1078 | ] 1079 | 1080 | [[package]] 1081 | name = "tower-cookies" 1082 | version = "0.9.0" 1083 | source = "registry+https://github.com/rust-lang/crates.io-index" 1084 | checksum = "40f38d941a2ffd8402b36e02ae407637a9caceb693aaf2edc910437db0f36984" 1085 | dependencies = [ 1086 | "async-trait", 1087 | "axum-core", 1088 | "cookie", 1089 | "futures-util", 1090 | "http", 1091 | "parking_lot", 1092 | "pin-project-lite", 1093 | "tower-layer", 1094 | "tower-service", 1095 | ] 1096 | 1097 | [[package]] 1098 | name = "tower-http" 1099 | version = "0.4.3" 1100 | source = "registry+https://github.com/rust-lang/crates.io-index" 1101 | checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" 1102 | dependencies = [ 1103 | "async-compression", 1104 | "base64 0.21.2", 1105 | "bitflags 2.4.0", 1106 | "bytes", 1107 | "futures-core", 1108 | "futures-util", 1109 | "http", 1110 | "http-body", 1111 | "http-range-header", 1112 | "httpdate", 1113 | "iri-string", 1114 | "mime", 1115 | "mime_guess", 1116 | "percent-encoding", 1117 | "pin-project-lite", 1118 | "tokio", 1119 | "tokio-util", 1120 | "tower", 1121 | "tower-layer", 1122 | "tower-service", 1123 | "tracing", 1124 | "uuid", 1125 | ] 1126 | 1127 | [[package]] 1128 | name = "tower-layer" 1129 | version = "0.3.2" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" 1132 | 1133 | [[package]] 1134 | name = "tower-service" 1135 | version = "0.3.2" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1138 | 1139 | [[package]] 1140 | name = "tower-sessions" 1141 | version = "0.2.2" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "dcc1a89e9b1b1020f56fe00224640e0212903b1626af70f7b6b2ace97cb11cfa" 1144 | dependencies = [ 1145 | "async-trait", 1146 | "axum-core", 1147 | "futures", 1148 | "http", 1149 | "parking_lot", 1150 | "serde", 1151 | "serde_json", 1152 | "thiserror", 1153 | "time", 1154 | "tower-cookies", 1155 | "tower-layer", 1156 | "tower-service", 1157 | "uuid", 1158 | ] 1159 | 1160 | [[package]] 1161 | name = "tracing" 1162 | version = "0.1.37" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1165 | dependencies = [ 1166 | "cfg-if", 1167 | "log", 1168 | "pin-project-lite", 1169 | "tracing-attributes", 1170 | "tracing-core", 1171 | ] 1172 | 1173 | [[package]] 1174 | name = "tracing-attributes" 1175 | version = "0.1.26" 1176 | source = "registry+https://github.com/rust-lang/crates.io-index" 1177 | checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" 1178 | dependencies = [ 1179 | "proc-macro2", 1180 | "quote", 1181 | "syn", 1182 | ] 1183 | 1184 | [[package]] 1185 | name = "tracing-core" 1186 | version = "0.1.31" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" 1189 | dependencies = [ 1190 | "once_cell", 1191 | "valuable", 1192 | ] 1193 | 1194 | [[package]] 1195 | name = "tracing-log" 1196 | version = "0.1.3" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" 1199 | dependencies = [ 1200 | "lazy_static", 1201 | "log", 1202 | "tracing-core", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "tracing-subscriber" 1207 | version = "0.3.17" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" 1210 | dependencies = [ 1211 | "matchers", 1212 | "nu-ansi-term", 1213 | "once_cell", 1214 | "regex", 1215 | "sharded-slab", 1216 | "smallvec", 1217 | "thread_local", 1218 | "tracing", 1219 | "tracing-core", 1220 | "tracing-log", 1221 | ] 1222 | 1223 | [[package]] 1224 | name = "try-lock" 1225 | version = "0.2.4" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 1228 | 1229 | [[package]] 1230 | name = "typenum" 1231 | version = "1.16.0" 1232 | source = "registry+https://github.com/rust-lang/crates.io-index" 1233 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 1234 | 1235 | [[package]] 1236 | name = "unicase" 1237 | version = "2.6.0" 1238 | source = "registry+https://github.com/rust-lang/crates.io-index" 1239 | checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" 1240 | dependencies = [ 1241 | "version_check", 1242 | ] 1243 | 1244 | [[package]] 1245 | name = "unicode-ident" 1246 | version = "1.0.11" 1247 | source = "registry+https://github.com/rust-lang/crates.io-index" 1248 | checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" 1249 | 1250 | [[package]] 1251 | name = "uuid" 1252 | version = "1.4.1" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" 1255 | dependencies = [ 1256 | "getrandom", 1257 | "serde", 1258 | ] 1259 | 1260 | [[package]] 1261 | name = "valuable" 1262 | version = "0.1.0" 1263 | source = "registry+https://github.com/rust-lang/crates.io-index" 1264 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 1265 | 1266 | [[package]] 1267 | name = "version_check" 1268 | version = "0.9.4" 1269 | source = "registry+https://github.com/rust-lang/crates.io-index" 1270 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1271 | 1272 | [[package]] 1273 | name = "want" 1274 | version = "0.3.1" 1275 | source = "registry+https://github.com/rust-lang/crates.io-index" 1276 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1277 | dependencies = [ 1278 | "try-lock", 1279 | ] 1280 | 1281 | [[package]] 1282 | name = "wasi" 1283 | version = "0.11.0+wasi-snapshot-preview1" 1284 | source = "registry+https://github.com/rust-lang/crates.io-index" 1285 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1286 | 1287 | [[package]] 1288 | name = "winapi" 1289 | version = "0.3.9" 1290 | source = "registry+https://github.com/rust-lang/crates.io-index" 1291 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1292 | dependencies = [ 1293 | "winapi-i686-pc-windows-gnu", 1294 | "winapi-x86_64-pc-windows-gnu", 1295 | ] 1296 | 1297 | [[package]] 1298 | name = "winapi-i686-pc-windows-gnu" 1299 | version = "0.4.0" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1302 | 1303 | [[package]] 1304 | name = "winapi-x86_64-pc-windows-gnu" 1305 | version = "0.4.0" 1306 | source = "registry+https://github.com/rust-lang/crates.io-index" 1307 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1308 | 1309 | [[package]] 1310 | name = "windows-sys" 1311 | version = "0.48.0" 1312 | source = "registry+https://github.com/rust-lang/crates.io-index" 1313 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1314 | dependencies = [ 1315 | "windows-targets", 1316 | ] 1317 | 1318 | [[package]] 1319 | name = "windows-targets" 1320 | version = "0.48.1" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" 1323 | dependencies = [ 1324 | "windows_aarch64_gnullvm", 1325 | "windows_aarch64_msvc", 1326 | "windows_i686_gnu", 1327 | "windows_i686_msvc", 1328 | "windows_x86_64_gnu", 1329 | "windows_x86_64_gnullvm", 1330 | "windows_x86_64_msvc", 1331 | ] 1332 | 1333 | [[package]] 1334 | name = "windows_aarch64_gnullvm" 1335 | version = "0.48.0" 1336 | source = "registry+https://github.com/rust-lang/crates.io-index" 1337 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 1338 | 1339 | [[package]] 1340 | name = "windows_aarch64_msvc" 1341 | version = "0.48.0" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 1344 | 1345 | [[package]] 1346 | name = "windows_i686_gnu" 1347 | version = "0.48.0" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 1350 | 1351 | [[package]] 1352 | name = "windows_i686_msvc" 1353 | version = "0.48.0" 1354 | source = "registry+https://github.com/rust-lang/crates.io-index" 1355 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 1356 | 1357 | [[package]] 1358 | name = "windows_x86_64_gnu" 1359 | version = "0.48.0" 1360 | source = "registry+https://github.com/rust-lang/crates.io-index" 1361 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 1362 | 1363 | [[package]] 1364 | name = "windows_x86_64_gnullvm" 1365 | version = "0.48.0" 1366 | source = "registry+https://github.com/rust-lang/crates.io-index" 1367 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 1368 | 1369 | [[package]] 1370 | name = "windows_x86_64_msvc" 1371 | version = "0.48.0" 1372 | source = "registry+https://github.com/rust-lang/crates.io-index" 1373 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 1374 | 1375 | [[package]] 1376 | name = "zstd" 1377 | version = "0.12.4" 1378 | source = "registry+https://github.com/rust-lang/crates.io-index" 1379 | checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" 1380 | dependencies = [ 1381 | "zstd-safe", 1382 | ] 1383 | 1384 | [[package]] 1385 | name = "zstd-safe" 1386 | version = "6.0.6" 1387 | source = "registry+https://github.com/rust-lang/crates.io-index" 1388 | checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" 1389 | dependencies = [ 1390 | "libc", 1391 | "zstd-sys", 1392 | ] 1393 | 1394 | [[package]] 1395 | name = "zstd-sys" 1396 | version = "2.0.8+zstd.1.5.5" 1397 | source = "registry+https://github.com/rust-lang/crates.io-index" 1398 | checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" 1399 | dependencies = [ 1400 | "cc", 1401 | "libc", 1402 | "pkg-config", 1403 | ] 1404 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | members = [ 4 | "common", 5 | "back_end", 6 | ] -------------------------------------------------------------------------------- /FullScreenCapture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbertovic/svelte-axum-project/ef122d643ddb8e113e6a5995acf33f9841f4f880/FullScreenCapture.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /MobileScreenCapture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbertovic/svelte-axum-project/ef122d643ddb8e113e6a5995acf33f9841f4f880/MobileScreenCapture.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # svelte-axum-project 2 | 3 | Starting project template for Rust Axum backend and Svelte frontend. Simple Single-Page-App (SPA) example. Does not use SvelteKit. 4 | 5 | ![](FullScreenCapture.png) 6 | ![](MobileScreenCapture.png) 7 | 8 | # New Version 0.4.2 9 | - migration of `axum-sessions` to `tower-sessions` see [pr#14](https://github.com/jbertovic/svelte-axum-project/pull/14) 10 | - removal of secret key warning due to migration 11 | 12 | # New Version 0.4.1 13 | - bumped version on backend; `axum` to 0.6.20, `axum-sessions` to 0.5, `tower-http` to 0.4 14 | - bumped versions on front-end; `vite-plugin-svelte` to 2.4.2, `svelte` to 4.0.5, `vite` to 4.4.5 15 | - backend changed how servedir works from `tower-http` for serving front end static assets 16 | 17 | # New Version 0.4.0 18 | - updated to `axum` 0.6 19 | - changes to State usage; how its setup with route and called from middleware 20 | - changes to ordering of parameters in functions; last parameter can consume request body 21 | - eliminated `axum::extract::RequestParts` with help from update on `axum-sessions` 22 | - updated to `axum-sessions` 0.4 to match 23 | - incremented `tokio` version to 1.24 24 | - old `axum` 0.5 version is kept under branch `v0.3_Axum0.5` 25 | 26 | # Help 27 | - We currently have a build script that builds the full stack concurrently for Linux. We would appreciate alternatives for Mac (should be minor tweak of Linux build script) and Windows. 28 | 29 | # Template 30 | ## Using Cargo 31 | - Must have cargo generate installed: `cargo install cargo-generate` 32 | - Then use `cargo generate jbertovic/svelte-axum-project -n ` 33 | 34 | ## Using git template 35 | - you can also just hit the "use this template" button in green on top of the repo 36 | - if you have gh cli installed check out `--template` option 37 | 38 | # Back end - Rust Axum 39 | - located in `./back_end` 40 | - serves front end directory 41 | - middleware for checking authorization header 42 | - middleware for checking session that user exists 43 | - store example that holds token secret for authorization 44 | - /api route example using authorization header 45 | - /secure route example using sessions for authorization 46 | 47 | Note there is no persistance beyond what's held in memory while the application is running 48 | 49 | run as `cargo run` from parent directory and not needed to run inside `./back_end` folder 50 | 51 | # Front end - Svelte 52 | - Located in `./front_end` 53 | - navbar with login and logout 54 | - secure page that shows session information once logged in 55 | - api fetch example, log in not required 56 | 57 | run as `npm run build` from inside the `./front_end` directory to build the static serve file directory. 58 | 59 | # Setup 60 | 61 | Install the following 62 | NodeJs - [Install](https://nodejs.org/en/download/) 63 | Rust - [Install](https://www.rust-lang.org/tools/install) 64 | 65 | Clone the repository 66 | - cd repository 67 | - inside the `./front_end` folder run `npm install` to download all module dependencies inside root directory of project 68 | - inside the `./front_end` folder run `npm run build` to bundle the js/svelte code into public folder 69 | - inside the top level folder run `cargo run` to start the the server 70 | - access in browser at http://localhost:8080/ 71 | 72 | In case you need to build both at once and use Linux, run `./build-fullstack.sh` -------------------------------------------------------------------------------- /back_end/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "svelte-axum-project" 3 | version = "0.4.2" 4 | edition = "2021" 5 | repository = "https://github.com/jbertovic/svelte-axum-project" 6 | keywords = ["template", "backend", "frontend", "axum", "svelte"] 7 | license = "" 8 | categories = [] 9 | description = "" 10 | readme = "README.md" 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | axum = { version = "0.6.20", features = ["headers"] } 15 | tower = "0.4.13" 16 | tower-http = { version = "0.4", features = ["full"] } 17 | tower-sessions = "0.2.2" 18 | tokio = { version = "1.24", features = ["full"] } 19 | tracing = "0.1" 20 | tracing-subscriber = { version = "0.3", features = ["env-filter"] } 21 | serde = { version = "1.0", features = ["derive"] } 22 | serde_json = "1.0.107" 23 | -------------------------------------------------------------------------------- /back_end/src/main.rs: -------------------------------------------------------------------------------- 1 | #![deny(clippy::all)] 2 | #![warn(clippy::pedantic)] 3 | #![warn(clippy::nursery)] 4 | #![allow(missing_docs)] 5 | 6 | use axum::Router; 7 | use std::net::SocketAddr; 8 | use std::{env, sync::Arc}; 9 | use tower_sessions::{MemoryStore, SessionManagerLayer}; 10 | use tracing::log::warn; 11 | use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; 12 | 13 | pub mod middlewares; 14 | pub mod routes; 15 | mod services; 16 | mod store; 17 | 18 | // SETUP Constants 19 | const SESSION_COOKIE_NAME: &str = "axum_svelte_session"; 20 | const FRONT_PUBLIC: &str = "./front_end/dist"; 21 | const SERVER_PORT: &str = "8080"; 22 | const SERVER_HOST: &str = "0.0.0.0"; 23 | 24 | /// Server that is split into a Frontend to serve static files (Svelte) and Backend 25 | /// Backend is further split into a non authorized area and a secure area 26 | /// The Back end is using 2 middleware: sessions (managing session data) and user_secure (checking for authorization) 27 | #[tokio::main] 28 | async fn main() { 29 | // start tracing - level set by either RUST_LOG env variable or defaults to debug 30 | tracing_subscriber::registry() 31 | .with(tracing_subscriber::EnvFilter::new( 32 | std::env::var("RUST_LOG").unwrap_or_else(|_| "svelte_axum_project=debug".into()), 33 | )) 34 | .with(tracing_subscriber::fmt::layer()) 35 | .init(); 36 | 37 | // configure server from environmental variables 38 | let (port, host) = from_env(); 39 | 40 | let addr: SocketAddr = format!("{}:{}", host, port) 41 | .parse() 42 | .expect("Can not parse address and port"); 43 | 44 | // create store for backend. Stores an api_token. 45 | let shared_state = Arc::new(store::Store::new("123456789")); 46 | 47 | // setup up sessions and store to keep track of session information 48 | let session_store = MemoryStore::default(); 49 | let session_layer = SessionManagerLayer::new(session_store).with_name(SESSION_COOKIE_NAME); 50 | 51 | // combine the front and backend into server 52 | let app = Router::new() 53 | .merge(services::front_public_route()) 54 | .merge(services::backend(session_layer, shared_state)); 55 | 56 | tracing::info!("listening on http://{}", addr); 57 | 58 | axum::Server::bind(&addr) 59 | .serve(app.into_make_service()) 60 | .with_graceful_shutdown(shutdown_signal()) 61 | .await 62 | .unwrap(); 63 | } 64 | 65 | /// Tokio signal handler that will wait for a user to press CTRL+C. 66 | /// We use this in our `Server` method `with_graceful_shutdown`. 67 | async fn shutdown_signal() { 68 | tokio::signal::ctrl_c() 69 | .await 70 | .expect("Expect shutdown signal handler"); 71 | println!("signal shutdown"); 72 | } 73 | 74 | // Variables from Environment or default to configure server 75 | // port, host, secret 76 | fn from_env() -> (String, String) { 77 | ( 78 | env::var("SERVER_PORT") 79 | .ok() 80 | .unwrap_or_else(|| SERVER_PORT.to_string()), 81 | env::var("SERVER_HOST") 82 | .ok() 83 | .unwrap_or_else(|| SERVER_HOST.to_string()), 84 | ) 85 | } 86 | -------------------------------------------------------------------------------- /back_end/src/middlewares.rs: -------------------------------------------------------------------------------- 1 | mod authenticator; 2 | mod usersecure; 3 | 4 | pub use authenticator::auth; 5 | pub use usersecure::user_secure; 6 | -------------------------------------------------------------------------------- /back_end/src/middlewares/authenticator.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use axum::{ 4 | extract::State, 5 | http::{self, Request, StatusCode}, 6 | middleware::Next, 7 | response::Response, 8 | Json, 9 | }; 10 | use serde::{Deserialize, Serialize}; 11 | 12 | use crate::store::Store; 13 | 14 | /// middleware function to authenticate authorization token 15 | /// check store that contains token and see if it matches authorization header starting with "Bearer" 16 | /// used example in axum docs on middleware 17 | /// 18 | /// Returns Error's in JSON format. 19 | #[allow(clippy::missing_errors_doc)] 20 | pub async fn auth( 21 | State(store): State>, 22 | req: Request, 23 | next: Next, 24 | ) -> Result)> { 25 | let auth_header = req 26 | .headers() 27 | .get(http::header::AUTHORIZATION) 28 | .and_then(|header| header.to_str().ok()); 29 | 30 | let auth_header = if let Some(auth_header) = auth_header { 31 | auth_header 32 | } else { 33 | tracing::debug!("Authorization header missing"); 34 | return Err((StatusCode::UNAUTHORIZED, Json(JsonError::unauthorized()))); 35 | }; 36 | 37 | tracing::debug!("Received Authorization Header: {}", auth_header); 38 | 39 | // check bearer authorization to see if it matches 40 | if store.api_token_check(auth_header) { 41 | Ok(next.run(req).await) 42 | } else { 43 | tracing::debug!("Authorization token does NOT match"); 44 | // return Ok(Json(json!( {"error": "Unauthorized"} )).into_response()); 45 | Err((StatusCode::UNAUTHORIZED, Json(JsonError::unauthorized()))) 46 | } 47 | } 48 | 49 | #[derive(Serialize, Deserialize)] 50 | pub struct JsonError { 51 | error: String, 52 | } 53 | 54 | impl JsonError { 55 | pub const fn new(error: String) -> Self { 56 | Self { error } 57 | } 58 | 59 | pub fn unauthorized() -> Self { 60 | Self { 61 | error: "Unauthorized".into(), 62 | } 63 | } 64 | 65 | pub fn internal() -> Self { 66 | Self { 67 | error: "Internal Server Error".into(), 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /back_end/src/middlewares/usersecure.rs: -------------------------------------------------------------------------------- 1 | use axum::{ 2 | http::{Request, StatusCode}, 3 | middleware::Next, 4 | response::Response, 5 | }; 6 | use tower_sessions::Session; 7 | 8 | #[allow(clippy::missing_errors_doc)] 9 | pub async fn user_secure( 10 | session: Session, 11 | req: Request, 12 | next: Next, 13 | ) -> Result { 14 | tracing::info!("Middleware: checking if user exists"); 15 | let user_id = session 16 | .get_value("user_id") 17 | .ok_or(StatusCode::UNAUTHORIZED)?; 18 | tracing::debug!("user_id Extracted: {}", user_id); 19 | 20 | // accepts all user but you could add a check here to match user access 21 | Ok(next.run(req).await) 22 | } 23 | -------------------------------------------------------------------------------- /back_end/src/routes.rs: -------------------------------------------------------------------------------- 1 | pub mod api; 2 | mod auth; 3 | mod notimplemented; 4 | pub mod session; 5 | 6 | pub use auth::login; 7 | pub use auth::logout; 8 | pub use notimplemented::not_implemented_route; 9 | -------------------------------------------------------------------------------- /back_end/src/routes/api.rs: -------------------------------------------------------------------------------- 1 | use axum::{response::IntoResponse, Json}; 2 | use serde_json::json; 3 | 4 | /// imitating an API response 5 | #[allow(clippy::unused_async)] 6 | pub async fn handler() -> impl IntoResponse { 7 | tracing::info!("Seeking api data"); 8 | Json( 9 | json!({"result": "ok", "message": "You've reached the backend API by using a valid token."}), 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /back_end/src/routes/auth.rs: -------------------------------------------------------------------------------- 1 | use axum::{response::IntoResponse, Json}; 2 | use serde::Deserialize; 3 | use serde_json::json; 4 | use tower_sessions::Session; 5 | 6 | /// route to handle log in 7 | #[allow(clippy::unused_async)] 8 | #[allow(clippy::missing_panics_doc)] 9 | pub async fn login(session: Session, Json(login): Json) -> impl IntoResponse { 10 | tracing::info!("Logging in user: {}", login.username); 11 | 12 | if check_password(&login.username, &login.password) { 13 | session.insert("user_id", login.username).unwrap(); 14 | Json(json!({"result": "ok"})) 15 | } else { 16 | Json(json!({"result": "error"})) 17 | } 18 | } 19 | 20 | /// route to handle log out 21 | #[allow(clippy::unused_async)] 22 | pub async fn logout(session: Session) -> impl IntoResponse { 23 | let user = session.get_value("user_id").unwrap_or_default(); 24 | tracing::info!("Logging out user: {}", user); 25 | // drop session 26 | session.flush(); 27 | Json(json!({"result": "ok"})) 28 | } 29 | 30 | // assume all passwords work 31 | const fn check_password(_username: &str, _password: &str) -> bool { 32 | true 33 | } 34 | 35 | #[derive(Deserialize)] 36 | pub struct Login { 37 | username: String, 38 | password: String, 39 | } 40 | -------------------------------------------------------------------------------- /back_end/src/routes/notimplemented.rs: -------------------------------------------------------------------------------- 1 | use axum::{body::Body, http::Request, response::IntoResponse}; 2 | 3 | #[allow(clippy::unused_async)] 4 | pub async fn not_implemented_route(req: Request) -> impl IntoResponse { 5 | // add which route is requesting this? 6 | format!("Route is planned but not yet implemented for {}", req.uri()) 7 | } 8 | -------------------------------------------------------------------------------- /back_end/src/routes/session.rs: -------------------------------------------------------------------------------- 1 | // print out session 2 | 3 | use axum::{response::IntoResponse, Json}; 4 | use serde_json::json; 5 | use tower_sessions::Session; 6 | 7 | /// output entire session object 8 | #[allow(clippy::unused_async)] 9 | pub async fn handler(session: Session) -> impl IntoResponse { 10 | tracing::info!("Seeking session info"); 11 | Json(json!({ "session": format!("{:?}", session) })) 12 | } 13 | 14 | /// output session data in json 15 | #[allow(clippy::unused_async)] 16 | pub async fn data_handler(session: Session) -> impl IntoResponse { 17 | tracing::info!("Seeking session data"); 18 | let user_id = session.get_value("user_id").unwrap_or_else(|| "".into()); 19 | Json(json!({ "user_id": user_id })) 20 | } 21 | -------------------------------------------------------------------------------- /back_end/src/services.rs: -------------------------------------------------------------------------------- 1 | use axum::{ 2 | error_handling::HandleErrorLayer, 3 | handler::HandlerWithoutStateExt, 4 | http::StatusCode, 5 | middleware, 6 | routing::{get, post}, 7 | BoxError, Router, 8 | }; 9 | use std::sync::Arc; 10 | use tower::ServiceBuilder; 11 | use tower_http::{services::ServeDir, trace::TraceLayer}; 12 | use tower_sessions::{SessionManagerLayer, SessionStore}; 13 | 14 | use crate::{ 15 | middlewares, routes, 16 | store::{self, Store}, 17 | FRONT_PUBLIC, 18 | }; 19 | 20 | // ********* 21 | // FRONT END 22 | // ********* 23 | // Front end to server svelte build bundle, css and index.html from public folder 24 | pub fn front_public_route() -> Router { 25 | Router::new() 26 | .fallback_service( 27 | ServeDir::new(FRONT_PUBLIC).not_found_service(handle_error.into_service()), 28 | ) 29 | .layer(TraceLayer::new_for_http()) 30 | } 31 | 32 | #[allow(clippy::unused_async)] 33 | async fn handle_error() -> (StatusCode, &'static str) { 34 | ( 35 | StatusCode::INTERNAL_SERVER_ERROR, 36 | "Something went wrong accessing static files...", 37 | ) 38 | } 39 | 40 | // ******** 41 | // BACK END 42 | // ******** 43 | // Back end server built form various routes that are either public, require auth, or secure login 44 | pub fn backend( 45 | session_layer: SessionManagerLayer, 46 | shared_state: Arc, 47 | ) -> Router { 48 | let session_service = ServiceBuilder::new() 49 | .layer(HandleErrorLayer::new(|_: BoxError| async { 50 | StatusCode::BAD_REQUEST 51 | })) 52 | .layer(session_layer); 53 | 54 | // could add tower::ServiceBuilder here to group layers, especially if you add more layers. 55 | // see https://docs.rs/axum/latest/axum/middleware/index.html#ordering 56 | Router::new() 57 | .merge(back_public_route()) 58 | .merge(back_auth_route()) 59 | .merge(back_token_route(shared_state)) 60 | .layer(session_service) 61 | } 62 | 63 | // ********* 64 | // BACKEND NON-AUTH 65 | // ********* 66 | // 67 | pub fn back_public_route() -> Router { 68 | Router::new() 69 | .route("/auth/session", get(routes::session::data_handler)) // gets session data 70 | .route("/auth/login", post(routes::login)) // sets username in session 71 | .route("/auth/logout", get(routes::logout)) // deletes username in session 72 | .route("/test", get(routes::not_implemented_route)) 73 | } 74 | 75 | // ********* 76 | // BACKEND SESSION 77 | // ********* 78 | // 79 | pub fn back_auth_route() -> Router { 80 | Router::new() 81 | .route("/secure", get(routes::session::handler)) 82 | .route_layer(middleware::from_fn(middlewares::user_secure)) 83 | } 84 | 85 | // ********* 86 | // BACKEND API 87 | // ********* 88 | // 89 | // invoked with State that stores API that is checked by the `middleware::auth` 90 | pub fn back_token_route(state: Arc) -> Router { 91 | Router::new() 92 | .route("/api", get(routes::api::handler)) 93 | .route_layer(middleware::from_fn_with_state( 94 | state.clone(), 95 | middlewares::auth, 96 | )) 97 | .with_state(state) 98 | } 99 | -------------------------------------------------------------------------------- /back_end/src/store.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone, Debug, Default)] 2 | pub struct Store { 3 | api_token: String, 4 | } 5 | 6 | impl Store { 7 | pub fn new(api_token: &str) -> Self { 8 | Self { 9 | api_token: api_token.to_string(), 10 | } 11 | } 12 | 13 | pub fn api_token_check(&self, auth_header: &str) -> bool { 14 | auth_header == format!("Bearer {}", self.api_token) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /build-fullstack.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # this script concurrently builds the frontend and backend. if either fails, the errors are logged. 4 | # this uses `script` to capture color of output and it writes the status to a file to capture error codes since `script`` does not return that. 5 | # stopping this script will orphan either build, so they will still consume system resources until finished. 6 | 7 | # if you wish to change to cargo run, the server will continue to run and still take up the port. 8 | # see https://stackoverflow.com/questions/11583562/how-to-kill-a-process-running-on-particular-port-in-linux 9 | # kill $(lsof -t -i:8080) (add -9 for extra power) 10 | 11 | npm_output=$(mktemp) 12 | cargo_output=$(mktemp) 13 | npm_status=$(mktemp) 14 | cargo_status=$(mktemp) 15 | 16 | # run in background, capture outputs, error codes 17 | script -q -c "cd front_end && npm i && npm run build; echo \$? > $npm_status" /dev/null > $npm_output 2> $npm_output 18 | npm_pid=$! 19 | 20 | script -q -c "cargo build; echo \$? > $cargo_status" /dev/null > $cargo_output 2> $cargo_output 21 | cargo_pid=$! 22 | 23 | wait $npm_pid 24 | npm_exit_status=$(cat $npm_status) 25 | 26 | # log if something failed 27 | if [ $npm_exit_status -ne 0 ]; then 28 | echo "Frontend build failed:" 29 | cat $npm_output 30 | fi 31 | 32 | wait $cargo_pid 33 | cargo_exit_status=$(cat $cargo_status) 34 | 35 | if [ $cargo_exit_status -ne 0 ]; then 36 | echo "Backend build failed:" 37 | cat $cargo_output 38 | fi 39 | 40 | rm $npm_output 41 | rm $cargo_output 42 | 43 | if [ $npm_exit_status -eq 0 ] && [ $cargo_exit_status -eq 0 ]; then 44 | echo "Build success" 45 | fi -------------------------------------------------------------------------------- /common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "common" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /common/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub fn add(left: usize, right: usize) -> usize { 2 | left + right 3 | } 4 | 5 | #[cfg(test)] 6 | mod tests { 7 | use super::*; 8 | 9 | #[test] 10 | fn it_works() { 11 | let result = add(2, 2); 12 | assert_eq!(result, 4); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /front_end/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | My svelte app with axum backend 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /front_end/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "bundler", 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | /** 7 | * svelte-preprocess cannot figure out whether you have 8 | * a value or a type, so tell TypeScript to enforce using 9 | * `import type` instead of `import` for Types. 10 | */ 11 | "verbatimModuleSyntax": true, 12 | "isolatedModules": true, 13 | "resolveJsonModule": true, 14 | /** 15 | * To have warnings / errors of the Svelte compiler at the 16 | * correct position, enable source maps by default. 17 | */ 18 | "sourceMap": true, 19 | "esModuleInterop": true, 20 | "skipLibCheck": true, 21 | /** 22 | * Typecheck JS in `.svelte` and `.js` files by default. 23 | * Disable this if you'd like to use dynamic types. 24 | */ 25 | "checkJs": true 26 | }, 27 | /** 28 | * Use global.d.ts instead of compilerOptions.types 29 | * to avoid limiting type declarations. 30 | */ 31 | "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"] 32 | } 33 | -------------------------------------------------------------------------------- /front_end/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-axum-project", 3 | "description": "svelte front end with axum backend template", 4 | "author": "Jas Bertovic", 5 | "version": "0.4.2", 6 | "type": "module", 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "vite build", 10 | "preview": "vite preview" 11 | }, 12 | "devDependencies": { 13 | "@sveltejs/vite-plugin-svelte": "^2.4.2", 14 | "svelte": "^4.0.5", 15 | "vite": "^4.4.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /front_end/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbertovic/svelte-axum-project/ef122d643ddb8e113e6a5995acf33f9841f4f880/front_end/public/favicon.ico -------------------------------------------------------------------------------- /front_end/public/global.css: -------------------------------------------------------------------------------- 1 | container { 2 | width: 300px; 3 | border: thin solid black; 4 | box-shadow: 5px 5px 5px lightgray; 5 | padding: 10px; 6 | } 7 | 8 | container.wider { 9 | width: 600px; 10 | } 11 | 12 | .mono { 13 | font-family: 'Courier New', Courier, monospace; 14 | } 15 | -------------------------------------------------------------------------------- /front_end/src/App.svelte: -------------------------------------------------------------------------------- 1 | 34 | 35 | 36 | 37 | 38 | 39 | {#if menu === 1} 40 |
41 | 42 | {#if !loggedin} 43 |

Requires Login

44 | {:else} 45 |

Logged In as {$user}

46 | {/if} 47 |

ABOUT

48 |
49 |
50 | {:else if menu === 2} 51 | 52 | {:else if menu === 3} 53 | 54 | {:else if menu === 4} 55 | 56 | {:else if menu === 5} 57 | 58 | {:else} 59 |

Page Not Found or Completed Yet

60 | {/if} 61 | 62 | 71 | -------------------------------------------------------------------------------- /front_end/src/app.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | position: relative; 3 | width: 100%; 4 | height: 100%; 5 | } 6 | 7 | body { 8 | color: #333; 9 | margin: 0; 10 | padding: 8px; 11 | box-sizing: border-box; 12 | font-family: Arial, Helvetica, sans-serif; 13 | } 14 | 15 | a { 16 | color: rgb(0,100,200); 17 | text-decoration: none; 18 | } 19 | 20 | a:hover { 21 | text-decoration: underline; 22 | } 23 | 24 | a:visited { 25 | color: rgb(0,80,160); 26 | } 27 | 28 | label { 29 | display: block; 30 | } 31 | 32 | input, button, select, textarea { 33 | font-family: inherit; 34 | font-size: inherit; 35 | -webkit-padding: 0.4em 0; 36 | padding: 0.4em; 37 | margin: 0 0 0.5em 0; 38 | box-sizing: border-box; 39 | border: 1px solid #ccc; 40 | border-radius: 2px; 41 | } 42 | 43 | input:disabled { 44 | color: #ccc; 45 | } 46 | 47 | button { 48 | color: #333; 49 | background-color: #f4f4f4; 50 | outline: none; 51 | } 52 | 53 | button:disabled { 54 | color: #999; 55 | } 56 | 57 | button:not(:disabled):active { 58 | background-color: #ddd; 59 | } 60 | 61 | button:focus { 62 | border-color: #666; 63 | } -------------------------------------------------------------------------------- /front_end/src/component/Navbar.svelte: -------------------------------------------------------------------------------- 1 | 39 | 40 | 64 | 65 | 198 | -------------------------------------------------------------------------------- /front_end/src/js/auth.js: -------------------------------------------------------------------------------- 1 | import {user} from './store.js'; 2 | 3 | export async function getSession() { 4 | const res = await fetch('/auth/session',{credentials: 'same-origin'}); 5 | let sessionResponse = await res.json(); 6 | if (sessionResponse.user_id !== '') { 7 | user.set(sessionResponse.user_id); 8 | } else 9 | { 10 | user.set(''); 11 | } 12 | } 13 | 14 | export async function postLogin(username, password) { 15 | const res = await fetch("/auth/login", { 16 | method: "POST", 17 | headers: { 18 | Accept: "application/json", 19 | "Content-Type": "application/json", 20 | }, 21 | body: JSON.stringify({ username: username, password: password }), 22 | }); 23 | return await res.json(); 24 | } 25 | 26 | export async function getLogout(username, password) { 27 | const res = await fetch("/auth/logout", {credentials: 'same-origin'}); 28 | 29 | let logoutResponse = await res.json(); 30 | if (logoutResponse.result == "error") { 31 | // may want to return an error here 32 | }else { 33 | user.set(''); 34 | } 35 | } -------------------------------------------------------------------------------- /front_end/src/js/fetch.js: -------------------------------------------------------------------------------- 1 | export async function getSecure() { 2 | let res = await fetch('/secure',{credentials: 'same-origin'}); 3 | let secureResponse = await res.json(); 4 | return JSON.stringify(secureResponse.session); 5 | } 6 | 7 | export async function getApi(api_token) { 8 | let res = await fetch('/api', { 9 | headers: { 10 | 'Authorization': 'Bearer '+ api_token, 11 | Accept: "application/json", 12 | }, 13 | }); 14 | return await res.json(); 15 | } -------------------------------------------------------------------------------- /front_end/src/js/store.js: -------------------------------------------------------------------------------- 1 | import { writable } from 'svelte/store'; 2 | export const user = writable(''); -------------------------------------------------------------------------------- /front_end/src/main.js: -------------------------------------------------------------------------------- 1 | import './app.css' 2 | import App from './App.svelte' 3 | 4 | const app = new App({ 5 | target: document.getElementById('app') 6 | }) 7 | 8 | export default app 9 | -------------------------------------------------------------------------------- /front_end/src/pages/Apicheck.svelte: -------------------------------------------------------------------------------- 1 | 14 | 15 |
16 | 17 |

18 | You can try using the default API to access api of backend server or 19 | you can try entering a bad token to see what happens. This can be 20 | used with or without logging in. 21 |

22 | 23 | 24 | 25 | 26 | 27 |

RESPONSE: {response}

28 |
29 |
30 | 31 | 45 | -------------------------------------------------------------------------------- /front_end/src/pages/Login.svelte: -------------------------------------------------------------------------------- 1 | 17 | 18 | {#if !$user} 19 | {#if errorMessage} 20 |
21 | {errorMessage} 22 |
23 | {/if} 24 |
25 | 26 |
27 | 28 | 34 | 35 | 41 | 42 |
43 |
44 |
45 | {:else} 46 |
47 | 48 | Logged in as: {$user}
49 | Now you may access the secure area from the Nav above 50 |
51 |
52 | {/if} 53 | 54 | 67 | -------------------------------------------------------------------------------- /front_end/src/pages/Logout.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 | 13 | {#if $user} 14 | You are still logged in as {$user}. 15 | {:else} 16 | You are now logged out. 17 | {/if} 18 | 19 |
20 | 21 | 30 | -------------------------------------------------------------------------------- /front_end/src/pages/Secure.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | 15 |

Logged in as {$user}

16 |

Response: {response}

17 |
18 |
19 | 20 | 35 | -------------------------------------------------------------------------------- /front_end/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /front_end/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' 2 | 3 | export default { 4 | // Consult https://svelte.dev/docs#compile-time-svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: vitePreprocess(), 7 | } -------------------------------------------------------------------------------- /front_end/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import { svelte } from '@sveltejs/vite-plugin-svelte' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [svelte()] 7 | }) 8 | --------------------------------------------------------------------------------