From 5d0a9bb2550a175304d4ff5eb3e572b3262c9c7f Mon Sep 17 00:00:00 2001 From: Edwin Eames Date: Tue, 10 Jun 2025 16:54:56 -0400 Subject: [PATCH] Issues vscode rreading errors --- .env | 3 + .gitignore | 1 + Cargo.lock | 358 +++++++++++++++++++---------------------- Cargo.toml | 12 +- schema.sql | 8 +- src/auth/auth.rs | 135 +++++++++++----- src/auth/structs.rs | 23 +-- src/company/company.rs | 83 ++++++++++ src/data/data.rs | 6 +- src/data/struct.rs | 10 -- src/main.rs | 32 ++-- src/state/data.rs | 25 ++- src/state/structs.rs | 11 +- 13 files changed, 421 insertions(+), 286 deletions(-) create mode 100755 .env create mode 100755 .gitignore diff --git a/.env b/.env new file mode 100755 index 0000000..5c39359 --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +DATABASE_URL=postgres://postgres:password@192.168.1.204:5432/fuelprices +JWT_SECRET=ThisIsAVeryLongSecretKey12345678 +FRONTEND_ORIGIN=http://localhost:9551 diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock index a3923ca..200c322 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" @@ -30,14 +30,14 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -79,12 +79,13 @@ dependencies = [ [[package]] name = "argon2" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4ce4441f99dbd377ca8a8f57b698c44d0d6e712d8329b5040da5a64aa1ce73" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" dependencies = [ "base64ct", "blake2", + "cpufeatures", "password-hash", ] @@ -96,7 +97,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -165,9 +166,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -192,9 +193,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" -version = "1.7.3" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] name = "bitflags" @@ -204,9 +205,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "blake2" @@ -228,9 +229,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" [[package]] name = "byteorder" @@ -246,29 +247,30 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.20" +version = "1.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" +checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" dependencies = [ "shlex", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-link", ] @@ -290,9 +292,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.2.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" dependencies = [ "crc-catalog", ] @@ -376,7 +378,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -509,7 +511,7 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "allocator-api2", ] @@ -644,21 +646,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -667,31 +670,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -699,67 +682,54 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] - [[package]] name = "idna" version = "1.0.3" @@ -773,9 +743,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -842,21 +812,21 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "libc", ] [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -904,22 +874,22 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] [[package]] name = "mio" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -994,12 +964,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", + "parking_lot_core 0.9.11", ] [[package]] @@ -1018,22 +988,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.11", + "redox_syscall 0.5.12", "smallvec", "windows-targets", ] [[package]] name = "password-hash" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", "rand_core", @@ -1078,7 +1048,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -1093,6 +1063,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -1105,7 +1084,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.25", + "zerocopy", ] [[package]] @@ -1167,11 +1146,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] @@ -1211,14 +1190,14 @@ dependencies = [ "getrandom", "libc", "untrusted 0.9.0", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustls" @@ -1243,9 +1222,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] name = "ryu" @@ -1286,7 +1265,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -1336,9 +1315,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -1374,18 +1353,18 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.15.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1426,6 +1405,7 @@ dependencies = [ "bitflags 1.3.2", "byteorder", "bytes", + "chrono", "crc", "crossbeam-queue", "dirs", @@ -1533,9 +1513,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.101" +version = "2.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "f6397daf94fa90f058bd0fd88429dd9e5738999cca8d701813c80723add80462" dependencies = [ "proc-macro2", "quote", @@ -1550,13 +1530,13 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -1585,7 +1565,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -1596,7 +1576,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -1632,9 +1612,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -1657,20 +1637,20 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.2" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", "bytes", "libc", "mio", - "parking_lot 0.12.3", + "parking_lot 0.12.4", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1681,7 +1661,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -1728,7 +1708,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "bytes", "futures-core", "futures-util", @@ -1765,9 +1745,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", ] @@ -1846,12 +1826,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -1875,9 +1849,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasite" @@ -1907,7 +1881,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", "wasm-bindgen-shared", ] @@ -1929,7 +1903,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1978,7 +1952,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" dependencies = [ - "redox_syscall 0.5.11", + "redox_syscall 0.5.12", "wasite", "web-sys", ] @@ -2007,9 +1981,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.61.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", @@ -2026,7 +2000,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -2037,7 +2011,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -2048,18 +2022,18 @@ checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-result" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ "windows-link", ] @@ -2073,6 +2047,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -2137,23 +2120,17 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -2163,43 +2140,23 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", "synstructure", ] -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "zerocopy-derive 0.7.35", -] - [[package]] name = "zerocopy" version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ - "zerocopy-derive 0.8.25", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", + "zerocopy-derive", ] [[package]] @@ -2210,7 +2167,7 @@ checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] [[package]] @@ -2230,15 +2187,26 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", "synstructure", ] [[package]] -name = "zerovec" -version = "0.10.4" +name = "zerotrie" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ "yoke", "zerofrom", @@ -2247,11 +2215,11 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn 2.0.102", ] diff --git a/Cargo.toml b/Cargo.toml index 4cd617a..cbaaa0c 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,13 +4,13 @@ version = "0.1.0" edition = "2021" [dependencies] -axum = "0.6" -tokio = { version = "1.0", features = ["full"] } -sqlx = { version = "0.6", features = ["runtime-tokio-rustls", "postgres"] } +axum = "0.6.20" +tokio = { version = "1.35.1", features = ["full"] } +sqlx = { version = "0.6", features = ["runtime-tokio-rustls", "postgres", "chrono"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -argon2 = "0.4" jsonwebtoken = "8.1" -chrono = "0.4" +chrono = { version = "0.4", features = ["serde"] } dotenv = "0.15" -tower-http = { version = "0.4", features = ["cors"] } \ No newline at end of file +tower-http = { version = "0.4", features = ["cors"] } +argon2 = { version = "0.5.3", features = ["std"] } diff --git a/schema.sql b/schema.sql index b2df84b..a8acdce 100755 --- a/schema.sql +++ b/schema.sql @@ -1,5 +1,9 @@ CREATE TABLE users ( id SERIAL PRIMARY KEY, username VARCHAR(255) UNIQUE NOT NULL, - password_hash TEXT NOT NULL -); \ No newline at end of file + password TEXT NOT NULL, + created TIMESTAMPTZ NOT NULL, + email VARCHAR(255), + last_login TIMESTAMPTZ, + owner INTEGER +); diff --git a/src/auth/auth.rs b/src/auth/auth.rs index d617142..f10556e 100755 --- a/src/auth/auth.rs +++ b/src/auth/auth.rs @@ -1,7 +1,7 @@ use axum::{ extract::{State, Json}, http::StatusCode, - response::IntoResponse, + response::{IntoResponse,Response}, routing::post, Router, }; @@ -12,6 +12,7 @@ use argon2::{ }; use jsonwebtoken::{encode, Header, EncodingKey}; + // Create auth router pub fn router() -> Router { Router::new() @@ -19,82 +20,140 @@ pub fn router() -> Router { .route("/auth/login", post(login)) } -// Register endpoint + +// A helper function to convert any error into a 500 Internal Server Error response. +fn internal_error(err: E) -> Response +where + E: std::error::Error, +{ + // Log the specific error to the server console for debugging. + eprintln!("Internal server error: {}", err); + + // Return a generic error message to the client. + ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(serde_json::json!({"error": "An internal server error occurred"})), + ) + .into_response() +} + + async fn register( State(state): State, Json(payload): Json, ) -> impl IntoResponse { - // Check if username exists - let exists = sqlx::query("SELECT 1 FROM users WHERE username = $1") + // 1. Check if username exists, handling potential database errors + let user_exists = match sqlx::query("SELECT 1 FROM users WHERE username = $1") .bind(&payload.username) - .fetch_optional(&state.db) + .fetch_optional(&*state.db) .await - .unwrap(); + { + Ok(maybe_row) => maybe_row.is_some(), + Err(e) => return internal_error(e), + }; - if exists.is_some() { - return (StatusCode::BAD_REQUEST, "Username already exists").into_response(); + if user_exists { + return ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!({ "error": "Username already exists" })), + ) + .into_response(); } - // Hash password + // 2. Hash password, handling potential hashing errors let salt = SaltString::generate(&mut OsRng); let argon2 = Argon2::default(); - let password_hash = argon2 - .hash_password(payload.password.as_bytes(), &salt) - .unwrap() - .to_string(); + let password_hash = match argon2.hash_password(payload.password.as_bytes(), &salt) { + Ok(hash) => hash.to_string(), + Err(e) => return internal_error(e), + }; - // Insert user + // 3. Insert user, handling potential database errors let result = sqlx::query_as::<_, User>( - "INSERT INTO users (username, password) VALUES ($1, $2) RETURNING id, username, password", + "INSERT INTO users (username, password, created, email, last_login, owner) VALUES ($1, $2, CURRENT_TIMESTAMP, $3, CURRENT_TIMESTAMP, NULL) RETURNING *", ) .bind(&payload.username) .bind(&password_hash) - .fetch_one(&state.db) - .await; + .bind(&payload.email) + .fetch_one(&*state.db) + .await; match result { Ok(user) => (StatusCode::CREATED, Json(user)).into_response(), - Err(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Failed to register").into_response(), + Err(e) => internal_error(e), } } -// Login endpoint -async fn login( + + + + +// Updated Login endpoint +pub async fn login( State(state): State, Json(payload): Json, ) -> impl IntoResponse { - // Fetch user - let user = sqlx::query_as::<_, User>("SELECT * FROM users WHERE username = $1") + // 1. Fetch user from the database + let user = match sqlx::query_as::<_, User>("SELECT * FROM users WHERE username = $1") .bind(&payload.username) - .fetch_optional(&state.db) + .fetch_optional(&*state.db) .await - .unwrap(); - - let user = match user { - Some(u) => u, - None => return (StatusCode::UNAUTHORIZED, "Invalid credentials").into_response(), + { + Ok(Some(user)) => user, + Ok(None) => { + // User not found. Use a generic error message to prevent username enumeration attacks. + return (StatusCode::UNAUTHORIZED, Json(serde_json::json!({ "error": "Invalid credentials" }))).into_response(); + } + Err(e) => return internal_error(e), // Database query failed }; - // Verify password - let parsed_hash = PasswordHash::new(&user.password).unwrap(); + // --- FIX: Trim whitespace from the password hash string --- + // This handles cases where the DB column is CHAR instead of VARCHAR and pads with spaces. + let trimmed_password_hash = user.password.trim(); + + // 2. Parse the TRIMMED hash from the database. + let parsed_hash = match PasswordHash::new(trimmed_password_hash) { + Ok(hash) => hash, + Err(e) => { + // This is a server error because the hash in the DB is malformed. + return internal_error(e); + } + }; + + // 3. Verify the plaintext password against the parsed hash if Argon2::default() .verify_password(payload.password.as_bytes(), &parsed_hash) .is_err() { - return (StatusCode::UNAUTHORIZED, "Invalid credentials").into_response(); + // Passwords do not match. + return (StatusCode::UNAUTHORIZED, Json(serde_json::json!({ "error": "Invalid credentials" }))).into_response(); } - // Generate JWT + // 4. Update last_login. If this fails, log it but don't fail the login. + let current_date = chrono::Utc::now().naive_utc(); + if let Err(e) = sqlx::query("UPDATE users SET last_login = $1 WHERE username = $2") + .bind(current_date) + .bind(&payload.username) + .execute(&*state.db) + .await + { + eprintln!("Failed to update last_login for user {}: {:?}", user.username, e); + } + + // 5. Generate JWT let claims = Claims { - sub: user.username, + sub: user.username.clone(), exp: (chrono::Utc::now() + chrono::Duration::hours(24)).timestamp() as usize, }; - let token = encode( + + let token = match encode( &Header::default(), &claims, &EncodingKey::from_secret(state.jwt_secret.as_bytes()), - ) - .unwrap(); + ) { + Ok(t) => t, + Err(e) => return internal_error(e), // JWT generation failed + }; - (StatusCode::OK, Json(serde_json::json!({ "token": token }))).into_response() -} \ No newline at end of file + (StatusCode::OK, Json(serde_json::json!({ "token": token, "user": user }))).into_response() +} diff --git a/src/auth/structs.rs b/src/auth/structs.rs index bc2e874..1c0b024 100755 --- a/src/auth/structs.rs +++ b/src/auth/structs.rs @@ -1,7 +1,16 @@ -// src/auth/structs.rs +use std::sync::Arc; +use sqlx::PgPool; use serde::{Deserialize, Serialize}; use sqlx::FromRow; -use sqlx::PgPool; +use chrono::NaiveDateTime; + + +#[derive(Clone)] +pub struct AppState { + pub db_url: String, + pub db: Arc, + pub jwt_secret: String, +} #[derive(Debug, Serialize, Deserialize, FromRow)] @@ -9,22 +18,18 @@ pub struct User { pub id: i32, pub username: String, pub password: String, - pub created: String, + pub created: Option, pub email: Option, - pub last_login: Option, + pub last_login: Option, pub owner: Option, } -#[derive(Debug, Clone)] -pub struct AppState { - pub db: PgPool, - pub jwt_secret: String, -} #[derive(Debug, Serialize, Deserialize)] pub struct RegisterRequest { pub username: String, pub password: String, + pub email: String, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/company/company.rs b/src/company/company.rs index e69de29..744d6d1 100644 --- a/src/company/company.rs +++ b/src/company/company.rs @@ -0,0 +1,83 @@ +use axum::{ + http::StatusCode, + response::{IntoResponse, Response}, + Json, Router, extract::State, + routing::post, +}; +use crate::auth::structs::AppState; +use sqlx::query_as; +use crate::company::structs::Company; + +pub async fn company_routes() -> Router { + let router = Router::new().route("/company", post(update_or_create_company)); + router +} + + +pub async fn update_or_create_company( + State(state): State, + Json(company): Json, +) -> Response { + let result = query_as::<_, Company>( + "SELECT * FROM company WHERE id = $1", + ) + .bind(company.id) + .fetch_optional(&*state.db) + .await; + + match result { + Ok(existing_company) => { + match existing_company { + Some(_) => { + // Update existing company + let result = sqlx::query( + "UPDATE company SET active = $2, name = $3, address = $4, town = $5, state = $6, phone = $7, owner_name = $8, owner_phone_number = $9, email = $10, user_id = $11 WHERE id = $1" + ) + .bind(company.id) + .bind(company.active) + .bind(company.name) + .bind(company.address) + .bind(company.town) + .bind(company.state) + .bind(company.phone) + .bind(company.owner_name) + .bind(company.owner_phone_number) + .bind(company.email) + .bind(company.user_id) + .execute(&*state.db) + .await; + + match result { + Ok(_) => (StatusCode::OK, "Company updated successfully".to_string()).into_response(), + Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error updating company: {}", e)).into_response(), + } + } + None => { + // Create new company + let result = sqlx::query( + "INSERT INTO company (active, created, name, address, town, state, phone, owner_name, owner_phone_number, email, user_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)" + ) + .bind(company.active) + .bind(chrono::Utc::now().naive_utc().date()) + .bind(company.name) + .bind(company.address) + .bind(company.town) + .bind(company.state) + .bind(company.phone) + .bind(company.owner_name) + .bind(company.owner_phone_number) + .bind(company.email) + .bind(company.user_id) + .execute(&*state.db) + .await; + + match result { + Ok(_) => (StatusCode::CREATED, "Company created successfully".to_string()).into_response(), + Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error creating company: {}", e)).into_response(), + } + } + } + } + Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error checking for existing company: {}", e)).into_response(), + } +} diff --git a/src/data/data.rs b/src/data/data.rs index 2b132f3..bf2260f 100644 --- a/src/data/data.rs +++ b/src/data/data.rs @@ -11,7 +11,11 @@ use crate::auth::structs::AppState; async fn get_user(State(state): State) -> impl IntoResponse { // Placeholder for user data retrieval logic // In a real application, you would query the database using state.db - (StatusCode::OK, "User data retrieved successfully") + let users = sqlx::query("SELECT * FROM users").fetch_all(&*state.db).await; + match users { + Ok(_users) => (StatusCode::OK, "User data retrieved successfully".to_string()).into_response(), + Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to retrieve users: {}", e)).into_response(), + } } // Define the router for the data module diff --git a/src/data/struct.rs b/src/data/struct.rs index 95d8f63..e69de29 100644 --- a/src/data/struct.rs +++ b/src/data/struct.rs @@ -1,10 +0,0 @@ -// src/data/struct.rs -use serde::{Deserialize, Serialize}; -use sqlx::FromRow; - -#[derive(Debug, Serialize, Deserialize, FromRow)] -pub struct County { - pub id: i32, - pub name: String, - pub state: i32, -} diff --git a/src/main.rs b/src/main.rs index 00a3105..0395ea6 100755 --- a/src/main.rs +++ b/src/main.rs @@ -1,38 +1,48 @@ use axum::{ http::{header, Method}, Router, + }; use std::env; use tower_http::cors::{CorsLayer, Any}; use crate::auth::structs::AppState; use crate::auth::auth::router as auth_router; use crate::data::data::router as data_router; -use crate::state::data::{get_counties_by_state, get_county_by_id}; +use crate::state::data::router as state_router; +use crate::company::company::company_routes; +use sqlx::PgPool; +use std::sync::Arc; mod auth; mod data; mod state; +mod company; #[tokio::main] async fn main() { // Load environment variables - dotenv::dotenv().ok(); let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); - let jwt_secret = env::var("JWT_SECRET").expect("JWT_SECRET must be set"); + let _jwt_secret = env::var("JWT_SECRET").expect("JWT_SECRET must be set"); let frontend_origin = env::var("FRONTEND_ORIGIN").unwrap_or_else(|_| "http://localhost:9551".to_string()); // Connect to PostgreSQL - let db = sqlx::PgPool::connect(&database_url) + let db_pool = PgPool::connect(&database_url) .await .expect("Failed to connect to database"); + let db = Arc::new(db_pool); + // Create app state - let state = AppState { db, jwt_secret }; + let state = AppState { + db_url: database_url.clone(), + db: db.clone(), + jwt_secret: env::var("JWT_SECRET").expect("JWT_SECRET must be set"), + }; // Configure CORS let cors = CorsLayer::new() - .allow_origin(frontend_origin.parse::().unwrap()) + .allow_origin(tower_http::cors::AllowOrigin::exact(frontend_origin.parse::().unwrap())) .allow_methods([Method::GET, Method::POST]) .allow_headers(Any); @@ -41,15 +51,13 @@ async fn main() { .route("/", axum::routing::get(|| async { "API is running" })) .merge(auth_router()) .merge(data_router()) - .route("/state/:state_abbr", axum::routing::get(get_counties_by_state)) - .route("/state/:state_abbr/:county_id", axum::routing::get(get_county_by_id)) - .layer(cors) - .with_state(state); + .merge(state_router()) + .merge(company_routes().await) + .with_state(state.clone()) + .layer(cors); // Print server status - // use std::io::Write; println!("Server is running on http://0.0.0.0:9552"); - // std::io::stdout().flush().unwrap(); // Run server axum::Server::bind(&"0.0.0.0:9552".parse().unwrap()) diff --git a/src/state/data.rs b/src/state/data.rs index fd4b767..270365a 100644 --- a/src/state/data.rs +++ b/src/state/data.rs @@ -2,23 +2,31 @@ use axum::{ extract::{Path, State}, response::Json, http::StatusCode, + Router, + routing::get, }; -use serde::Serialize; -use sqlx::PgPool; -use crate::auth::structs::AppState; // Import AppState - +use crate::auth::structs::AppState; use crate::state::structs::{County, ErrorResponse}; + +pub fn router() -> Router { + Router::new() + .route("/state/:state_abbr", get(get_counties_by_state)) + .route("/state/:state_abbr/:county_id", get(get_county_by_id)) +} + + + pub async fn get_counties_by_state( - State(app_state): State, // Changed from State to State + State(app_state): State, Path(state_abbr): Path, ) -> Result>, (StatusCode, Json)> { - let state_abbr_upper = state_abbr.to_uppercase(); // Ensure consistent casing for DB query + let state_abbr_upper = state_abbr.to_uppercase(); println!("Querying counties for state: {}", state_abbr_upper); match sqlx::query_as::<_, County>("SELECT id, name, state FROM county WHERE UPPER(state) = $1 ORDER BY name ASC") .bind(&state_abbr_upper) - .fetch_all(&app_state.db) // Use app_state.db to access the pool + .fetch_all(&*app_state.db) .await { Ok(counties) => { @@ -55,7 +63,7 @@ pub async fn get_county_by_id( match sqlx::query_as::<_, County>("SELECT id, name, state FROM county WHERE UPPER(state) = $1 AND id = $2") .bind(&state_abbr_upper) .bind(county_id) - .fetch_one(&app_state.db) + .fetch_one(&*app_state.db) .await { Ok(county) => Ok(Json(county)), @@ -76,3 +84,4 @@ pub async fn get_county_by_id( } } } + diff --git a/src/state/structs.rs b/src/state/structs.rs index a0fe808..c03fa8e 100644 --- a/src/state/structs.rs +++ b/src/state/structs.rs @@ -1,13 +1,14 @@ -use serde::Serialize; +use serde::{Deserialize, Serialize}; use sqlx::FromRow; -#[derive(Serialize, FromRow)] +#[derive(Debug, Serialize, Deserialize, FromRow)] pub struct County { - id: i32, // Assuming county table has an integer primary key id - name: String, - state: String, // This will be the state abbreviation + pub id: i32, + pub name: String, + pub state: String, } + #[derive(Serialize)] pub struct ErrorResponse { pub error: String,