multi-hotel-refactor #3
49
.gitea/workflows/deploy_api.yml
Normal file
49
.gitea/workflows/deploy_api.yml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
name: Deploy API
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- multi-hotel-refactor
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name : Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build Docker image
|
||||||
|
run: |
|
||||||
|
docker build -t hotel-demo:latest .
|
||||||
|
|
||||||
|
- name: Save Docker image
|
||||||
|
run: |
|
||||||
|
docker save hotel-demo:latest -o hotel-demo.tar
|
||||||
|
|
||||||
|
|
||||||
|
- name: setup SSH
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_ed25519
|
||||||
|
chmod 600 ~/.ssh/id_ed25519
|
||||||
|
ssh-keyscan 79.137.75.155 >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
#Upload
|
||||||
|
scp hotel-demo.tar deploy@79.137.75.155:/tmp
|
||||||
|
|
||||||
|
docker load -i hotel-demo.tar
|
||||||
|
|
||||||
|
docker stop hotel-demo || true
|
||||||
|
docker rm hotel-demo || true
|
||||||
|
|
||||||
|
docker run -d \
|
||||||
|
--name hotel-demo \
|
||||||
|
-e JWT_SECRET=${{ secrets.JWT_SECRET }} \
|
||||||
|
-v "/var/lib/hotel-demo/:/app/db" \
|
||||||
|
-p 5090:7080 \
|
||||||
|
hotel-demo:latest
|
||||||
|
|
||||||
|
rm hotel-demo:latest
|
||||||
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
/target
|
/target
|
||||||
|
/.vscode
|
||||||
|
|
||||||
|
|
||||||
.env
|
.env
|
||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"todo-tree.tree.showBadges": true
|
|
||||||
}
|
|
||||||
14
.vscode/tasks.json
vendored
14
.vscode/tasks.json
vendored
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "2.0.0",
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"type": "cargo",
|
|
||||||
"command": "build",
|
|
||||||
"problemMatcher": [
|
|
||||||
"$rustc"
|
|
||||||
],
|
|
||||||
"group": "build",
|
|
||||||
"label": "rust: cargo build"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
460
Cargo.lock
generated
460
Cargo.lock
generated
@@ -255,6 +255,12 @@ version = "1.0.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg_aliases"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.42"
|
version = "0.4.42"
|
||||||
@@ -265,7 +271,7 @@ dependencies = [
|
|||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-link 0.2.0",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -289,16 +295,6 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "core-foundation"
|
|
||||||
version = "0.9.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
|
||||||
dependencies = [
|
|
||||||
"core-foundation-sys",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation-sys"
|
name = "core-foundation-sys"
|
||||||
version = "0.8.7"
|
version = "0.8.7"
|
||||||
@@ -387,31 +383,6 @@ version = "0.15.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "encoding_rs"
|
|
||||||
version = "0.8.35"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "equivalent"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "errno"
|
|
||||||
version = "0.3.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fallible-iterator"
|
name = "fallible-iterator"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@@ -424,12 +395,6 @@ version = "0.1.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fastrand"
|
|
||||||
version = "2.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "find-msvc-tools"
|
name = "find-msvc-tools"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@@ -448,21 +413,6 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "foreign-types"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
|
||||||
dependencies = [
|
|
||||||
"foreign-types-shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "foreign-types-shared"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
@@ -564,9 +514,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"r-efi",
|
"r-efi",
|
||||||
"wasi 0.14.7+wasi-0.2.4",
|
"wasi 0.14.7+wasi-0.2.4",
|
||||||
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -575,25 +527,6 @@ version = "0.31.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "h2"
|
|
||||||
version = "0.4.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
|
|
||||||
dependencies = [
|
|
||||||
"atomic-waker",
|
|
||||||
"bytes",
|
|
||||||
"fnv",
|
|
||||||
"futures-core",
|
|
||||||
"futures-sink",
|
|
||||||
"http",
|
|
||||||
"indexmap",
|
|
||||||
"slab",
|
|
||||||
"tokio",
|
|
||||||
"tokio-util",
|
|
||||||
"tracing",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.14.5"
|
version = "0.14.5"
|
||||||
@@ -609,12 +542,6 @@ dependencies = [
|
|||||||
"foldhash",
|
"foldhash",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashbrown"
|
|
||||||
version = "0.16.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashlink"
|
name = "hashlink"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@@ -672,6 +599,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tower-http",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -731,7 +659,6 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"h2",
|
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
@@ -758,22 +685,7 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
]
|
"webpki-roots",
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hyper-tls"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"http-body-util",
|
|
||||||
"hyper",
|
|
||||||
"hyper-util",
|
|
||||||
"native-tls",
|
|
||||||
"tokio",
|
|
||||||
"tokio-native-tls",
|
|
||||||
"tower-service",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -795,11 +707,9 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"socket2",
|
||||||
"system-configuration",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-registry",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -928,16 +838,6 @@ dependencies = [
|
|||||||
"icu_properties",
|
"icu_properties",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "indexmap"
|
|
||||||
version = "2.12.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
|
|
||||||
dependencies = [
|
|
||||||
"equivalent",
|
|
||||||
"hashbrown 0.16.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inout"
|
name = "inout"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@@ -1022,12 +922,6 @@ dependencies = [
|
|||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "linux-raw-sys"
|
|
||||||
version = "0.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "litemap"
|
name = "litemap"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@@ -1050,6 +944,12 @@ version = "0.4.28"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lru-slab"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchit"
|
name = "matchit"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
@@ -1088,23 +988,6 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "native-tls"
|
|
||||||
version = "0.2.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"log",
|
|
||||||
"openssl",
|
|
||||||
"openssl-probe",
|
|
||||||
"openssl-sys",
|
|
||||||
"schannel",
|
|
||||||
"security-framework",
|
|
||||||
"security-framework-sys",
|
|
||||||
"tempfile",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint"
|
name = "num-bigint"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@@ -1154,50 +1037,6 @@ version = "1.21.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl"
|
|
||||||
version = "0.10.75"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cfg-if",
|
|
||||||
"foreign-types",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
"openssl-macros",
|
|
||||||
"openssl-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl-macros"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl-probe"
|
|
||||||
version = "0.1.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl-sys"
|
|
||||||
version = "0.9.111"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
"pkg-config",
|
|
||||||
"vcpkg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.4"
|
version = "0.12.4"
|
||||||
@@ -1299,6 +1138,61 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn"
|
||||||
|
version = "0.11.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"cfg_aliases",
|
||||||
|
"pin-project-lite",
|
||||||
|
"quinn-proto",
|
||||||
|
"quinn-udp",
|
||||||
|
"rustc-hash",
|
||||||
|
"rustls",
|
||||||
|
"socket2",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"web-time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn-proto"
|
||||||
|
version = "0.11.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"getrandom 0.3.3",
|
||||||
|
"lru-slab",
|
||||||
|
"rand",
|
||||||
|
"ring",
|
||||||
|
"rustc-hash",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"slab",
|
||||||
|
"thiserror",
|
||||||
|
"tinyvec",
|
||||||
|
"tracing",
|
||||||
|
"web-time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn-udp"
|
||||||
|
version = "0.5.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
|
||||||
|
dependencies = [
|
||||||
|
"cfg_aliases",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"socket2",
|
||||||
|
"tracing",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.40"
|
version = "1.0.40"
|
||||||
@@ -1385,37 +1279,34 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.12.24"
|
version = "0.12.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f"
|
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
"encoding_rs",
|
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2",
|
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-rustls",
|
"hyper-rustls",
|
||||||
"hyper-tls",
|
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"mime",
|
|
||||||
"native-tls",
|
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"quinn",
|
||||||
|
"rustls",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"sync_wrapper",
|
"sync_wrapper",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-native-tls",
|
"tokio-rustls",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
@@ -1423,6 +1314,7 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
|
"webpki-roots",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1460,17 +1352,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
|
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustc-hash"
|
||||||
version = "1.1.2"
|
version = "2.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"errno",
|
|
||||||
"libc",
|
|
||||||
"linux-raw-sys",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
@@ -1479,6 +1364,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
|
checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"rustls-webpki",
|
"rustls-webpki",
|
||||||
"subtle",
|
"subtle",
|
||||||
@@ -1491,6 +1377,7 @@ version = "1.13.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a"
|
checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"web-time",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1517,15 +1404,6 @@ version = "1.0.20"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "schannel"
|
|
||||||
version = "0.1.28"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
|
|
||||||
dependencies = [
|
|
||||||
"windows-sys 0.61.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scheduled-thread-pool"
|
name = "scheduled-thread-pool"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
@@ -1541,29 +1419,6 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "security-framework"
|
|
||||||
version = "2.11.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"core-foundation",
|
|
||||||
"core-foundation-sys",
|
|
||||||
"libc",
|
|
||||||
"security-framework-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "security-framework-sys"
|
|
||||||
version = "2.15.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
|
|
||||||
dependencies = [
|
|
||||||
"core-foundation-sys",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.226"
|
version = "1.0.226"
|
||||||
@@ -1733,40 +1588,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "system-configuration"
|
|
||||||
version = "0.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"core-foundation",
|
|
||||||
"system-configuration-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "system-configuration-sys"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
|
|
||||||
dependencies = [
|
|
||||||
"core-foundation-sys",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tempfile"
|
|
||||||
version = "3.23.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
|
|
||||||
dependencies = [
|
|
||||||
"fastrand",
|
|
||||||
"getrandom 0.3.3",
|
|
||||||
"once_cell",
|
|
||||||
"rustix",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.16"
|
version = "2.0.16"
|
||||||
@@ -1828,6 +1649,21 @@ dependencies = [
|
|||||||
"zerovec",
|
"zerovec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.47.1"
|
version = "1.47.1"
|
||||||
@@ -1859,16 +1695,6 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tokio-native-tls"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
|
||||||
dependencies = [
|
|
||||||
"native-tls",
|
|
||||||
"tokio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-rustls"
|
name = "tokio-rustls"
|
||||||
version = "0.26.4"
|
version = "0.26.4"
|
||||||
@@ -1891,19 +1717,6 @@ dependencies = [
|
|||||||
"tungstenite",
|
"tungstenite",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tokio-util"
|
|
||||||
version = "0.7.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594"
|
|
||||||
dependencies = [
|
|
||||||
"bytes",
|
|
||||||
"futures-core",
|
|
||||||
"futures-sink",
|
|
||||||
"pin-project-lite",
|
|
||||||
"tokio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower"
|
name = "tower"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
@@ -1922,9 +1735,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-http"
|
name = "tower-http"
|
||||||
version = "0.6.6"
|
version = "0.6.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
|
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -2175,6 +1988,25 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-time"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.62.0"
|
version = "0.62.0"
|
||||||
@@ -2183,9 +2015,9 @@ checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-implement",
|
"windows-implement",
|
||||||
"windows-interface",
|
"windows-interface",
|
||||||
"windows-link 0.2.0",
|
"windows-link",
|
||||||
"windows-result 0.4.0",
|
"windows-result",
|
||||||
"windows-strings 0.5.0",
|
"windows-strings",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2210,54 +2042,19 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-link"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-link"
|
name = "windows-link"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-registry"
|
|
||||||
version = "0.5.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
"windows-result 0.3.4",
|
|
||||||
"windows-strings 0.4.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-result"
|
|
||||||
version = "0.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-result"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
|
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link 0.2.0",
|
"windows-link",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-strings"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2266,7 +2063,7 @@ version = "0.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
|
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-link 0.2.0",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2287,15 +2084,6 @@ dependencies = [
|
|||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.61.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link 0.2.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "windows-targets"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ rand_core = {version = "0.6.4", features = ["getrandom"]}
|
|||||||
futures-util = {version = "0.3.31"}
|
futures-util = {version = "0.3.31"}
|
||||||
uuid = {version = "1.18.1", features = ["serde"] }
|
uuid = {version = "1.18.1", features = ["serde"] }
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
reqwest = { version = "0.12.24", features = ["json","blocking"] }
|
reqwest = { version = "0.12.28", default-features = false, features = ["json","blocking", "rustls-tls"] }
|
||||||
|
tower-http = { version = "0.6.7", features = ["cors"] }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
FROM rust:latest AS builder
|
|
||||||
WORKDIR /app
|
|
||||||
COPY . .
|
|
||||||
RUN cargo build --release
|
|
||||||
|
|
||||||
FROM debian:bookworm-slim
|
|
||||||
WORKDIR /app
|
|
||||||
COPY --from=builder /app/target/release/hotel-api-rs /usr/local/bin/hotel-api-rs
|
|
||||||
|
|
||||||
# Create the directory where DB will be stored
|
|
||||||
RUN mkdir -p /db
|
|
||||||
|
|
||||||
# Expose API port
|
|
||||||
EXPOSE 8080
|
|
||||||
|
|
||||||
CMD ["/usr/local/bin/hotel-api-rs"]
|
|
||||||
37
authbruh.rs
37
authbruh.rs
@@ -1,37 +0,0 @@
|
|||||||
use std::time::Duration;
|
|
||||||
use axum::{
|
|
||||||
body::{to_bytes, Body},
|
|
||||||
http::{Request as HttpRequest, StatusCode},
|
|
||||||
middleware::Next,
|
|
||||||
response::{Response, IntoResponse},
|
|
||||||
Json,
|
|
||||||
extract::{Path, State, FromRequest}
|
|
||||||
};
|
|
||||||
use axum::extract::Request as ExtractRequest;
|
|
||||||
use jsonwebtoken::{decode, DecodingKey, Validation, encode, EncodingKey, Header};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use serde_json::Value;
|
|
||||||
use chrono::{Utc};
|
|
||||||
use rusqlite::{params, Connection, OptionalExtension};
|
|
||||||
|
|
||||||
//use crate::utils::db_pool::;
|
|
||||||
use crate::utils::db_pool::{
|
|
||||||
HotelPool,
|
|
||||||
AppState,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn clean_auth_loging(
|
|
||||||
State(state): State<AppState>,
|
|
||||||
// LoginPayload(payload): LoginPayload,
|
|
||||||
) -> impl IntoResponse {
|
|
||||||
// You can access state.pool and state.jwt_secret here
|
|
||||||
format!("Got secret: {}", state.jwt_secret)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn internal_error<E: std::fmt::Display>(err: E) -> (StatusCode, String) {
|
|
||||||
(StatusCode::INTERNAL_SERVER_ERROR, format!("Internal error: {}", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BIN
db/1.sqlite
BIN
db/1.sqlite
Binary file not shown.
BIN
db/1.sqlite-shm
BIN
db/1.sqlite-shm
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
db/auth_demo.sqlite
Normal file
BIN
db/auth_demo.sqlite
Normal file
Binary file not shown.
BIN
db/demo-db/1 copy.sqlite
Normal file
BIN
db/demo-db/1 copy.sqlite
Normal file
Binary file not shown.
BIN
db/demo-db/auth_demo.sqlite
Normal file
BIN
db/demo-db/auth_demo.sqlite
Normal file
Binary file not shown.
@@ -1,51 +0,0 @@
|
|||||||
CREATE TABLE rooms (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
number TEXT NOT NULL UNIQUE,
|
|
||||||
status TEXT NOT NULL DEFAULT 'clean'
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS "conversation" (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
|
|
||||||
`creator_id` INTEGER,
|
|
||||||
`title` TEXT,
|
|
||||||
`created_at` TEXT DEFAULT (CURRENT_TIMESTAMP)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS "message" (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
`conversation_id` INTEGER REFERENCES `conversation`(`id`),
|
|
||||||
`sender_id` INTEGER NOT NULL, `content` TEXT NOT NULL,
|
|
||||||
`sent_at` TEXT DEFAULT (CURRENT_TIMESTAMP)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE "conversation_participants" (
|
|
||||||
`conversation_id` INTEGER NOT NULL REFERENCES `conversation`(`id`),
|
|
||||||
`user_id` INTEGER NOT NULL,
|
|
||||||
`joined_at` TEXT DEFAULT (CURRENT_TIMESTAMP)
|
|
||||||
PRIMARY KEY (conversation_id, user_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS "inventory" (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
`amount` INTEGER,
|
|
||||||
`item_name` TEXT,
|
|
||||||
`user_id` INT,
|
|
||||||
`updated_at` TEXT DEFAULT (CURRENT_TIMESTAMP)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS "room_history" (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
`room_id` INTEGER NOT NULL REFERENCES `rooms`(`id`),
|
|
||||||
`room_number` TEXT NOT NULL,
|
|
||||||
`status` TEXT,
|
|
||||||
`updated_at` TEXT DEFAULT CURRENT_TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS "inventory_history" (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
|
|
||||||
`item_id` INTEGER NOT NULL REFERENCES `inventory`(`id`),
|
|
||||||
`amount` INTEGER NOT NULL,
|
|
||||||
`item_name` TEXT,
|
|
||||||
`user_id` INT,
|
|
||||||
`updated_at` TEXT DEFAULT (CURRENT_TIMESTAMP));
|
|
||||||
|
|
||||||
BIN
db/test_backup/2 copy.sqlite
Normal file
BIN
db/test_backup/2 copy.sqlite
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,6 +0,0 @@
|
|||||||
id INT
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
token_hash TEXT NOT NULL,
|
|
||||||
device_id TEXT NOT NULL,
|
|
||||||
user_agent TEXT NOT NULL,
|
|
||||||
hotel_id TEXT
|
|
||||||
Binary file not shown.
@@ -1,25 +1,21 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
extract::{
|
|
||||||
FromRequest, Request
|
|
||||||
},
|
|
||||||
http::StatusCode,
|
|
||||||
Json,
|
Json,
|
||||||
|
extract::{FromRequest, Request},
|
||||||
|
http::StatusCode,
|
||||||
};
|
};
|
||||||
use chrono::NaiveDateTime;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct CreateConversationValues {
|
pub struct CreateConversationValues {
|
||||||
//pub creator_id: i32, // already in token ?
|
//pub creator_id: i32, // already in token ?
|
||||||
pub title: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CreateConversationPayload(pub CreateConversationValues);
|
pub struct CreateConversationPayload(pub CreateConversationValues);
|
||||||
|
|
||||||
impl<S> FromRequest<S> for CreateConversationPayload
|
impl<S> FromRequest<S> for CreateConversationPayload
|
||||||
where S: Send + Sync,
|
where
|
||||||
|
S: Send + Sync,
|
||||||
{
|
{
|
||||||
type Rejection = (StatusCode, String);
|
type Rejection = (StatusCode, String);
|
||||||
|
|
||||||
@@ -29,21 +25,20 @@ where S: Send + Sync,
|
|||||||
.map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?;
|
.map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?;
|
||||||
|
|
||||||
Ok(CreateConversationPayload(payload))
|
Ok(CreateConversationPayload(payload))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct AddUserConversationValues {
|
pub struct AddUserConversationValues {
|
||||||
pub conv_id: u32,
|
pub conv_id: u32,
|
||||||
pub users: Vec<u32>
|
pub users: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AddUserConversationPayload(pub AddUserConversationValues);
|
pub struct AddUserConversationPayload(pub AddUserConversationValues);
|
||||||
|
|
||||||
impl<S> FromRequest<S> for AddUserConversationPayload
|
impl<S> FromRequest<S> for AddUserConversationPayload
|
||||||
where S: Send + Sync,
|
where
|
||||||
|
S: Send + Sync,
|
||||||
{
|
{
|
||||||
type Rejection = (StatusCode, String);
|
type Rejection = (StatusCode, String);
|
||||||
|
|
||||||
@@ -53,7 +48,6 @@ where S: Send + Sync,
|
|||||||
.map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?;
|
.map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?;
|
||||||
|
|
||||||
Ok(AddUserConversationPayload(payload))
|
Ok(AddUserConversationPayload(payload))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +60,8 @@ pub struct SendMessageValues{
|
|||||||
pub struct SendMessagePayload(pub SendMessageValues);
|
pub struct SendMessagePayload(pub SendMessageValues);
|
||||||
|
|
||||||
impl<S> FromRequest<S> for SendMessagePayload
|
impl<S> FromRequest<S> for SendMessagePayload
|
||||||
where S: Send + Sync,
|
where
|
||||||
|
S: Send + Sync,
|
||||||
{
|
{
|
||||||
type Rejection = (StatusCode, String);
|
type Rejection = (StatusCode, String);
|
||||||
|
|
||||||
@@ -76,11 +71,9 @@ where S: Send + Sync,
|
|||||||
.map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?;
|
.map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?;
|
||||||
|
|
||||||
Ok(SendMessagePayload(payload))
|
Ok(SendMessagePayload(payload))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct GetMessagesValues {
|
pub struct GetMessagesValues {
|
||||||
pub conv_id: u32,
|
pub conv_id: u32,
|
||||||
@@ -90,7 +83,8 @@ pub struct GetMessagesValues{
|
|||||||
pub struct GetMessagesPayload(pub GetMessagesValues);
|
pub struct GetMessagesPayload(pub GetMessagesValues);
|
||||||
|
|
||||||
impl<S> FromRequest<S> for GetMessagesPayload
|
impl<S> FromRequest<S> for GetMessagesPayload
|
||||||
where S: Send + Sync,
|
where
|
||||||
|
S: Send + Sync,
|
||||||
{
|
{
|
||||||
type Rejection = (StatusCode, String);
|
type Rejection = (StatusCode, String);
|
||||||
|
|
||||||
@@ -100,7 +94,5 @@ where S: Send + Sync,
|
|||||||
.map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?;
|
.map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?;
|
||||||
|
|
||||||
Ok(GetMessagesPayload(payload))
|
Ok(GetMessagesPayload(payload))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,125 +1,298 @@
|
|||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
Json, extract::{
|
Json,
|
||||||
FromRequest,FromRequestParts, State,
|
extract::{FromRequest, FromRequestParts, Path, State},
|
||||||
|
http::StatusCode,
|
||||||
}, http::StatusCode, response::{IntoResponse, sse::KeepAlive}
|
response::{IntoResponse, sse::KeepAlive},
|
||||||
|
|
||||||
};
|
};
|
||||||
//use axum::extract::ws::Message;
|
//use axum::extract::ws::Message;
|
||||||
use chrono::NaiveDateTime;
|
use rusqlite::OptionalExtension;
|
||||||
use rusqlite::{Name, params};
|
use rusqlite::{Name, Statement, params};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::{json, to_value};
|
use serde_json::{json, to_value};
|
||||||
|
|
||||||
use crate::chat::extractor::{
|
use crate::chat::extractor::{
|
||||||
AddUserConversationPayload, CreateConversationPayload, GetMessagesPayload, SendMessagePayload
|
AddUserConversationPayload, CreateConversationPayload, GetMessagesPayload, SendMessagePayload,
|
||||||
};
|
};
|
||||||
use crate::utils::db_pool::{AppState};
|
|
||||||
use crate::utils::auth::AuthClaims;
|
use crate::utils::auth::AuthClaims;
|
||||||
|
use crate::utils::db_pool::AppState;
|
||||||
|
|
||||||
|
//TODO: update conversation title
|
||||||
|
//FIXME: make a default title if empty
|
||||||
pub async fn create_conversation(
|
pub async fn create_conversation(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||||
CreateConversationPayload(payload): CreateConversationPayload
|
CreateConversationPayload(payload): CreateConversationPayload,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
||||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||||
|
|
||||||
let conn = match pool.get() {
|
let conn = match pool.get() {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error"))
|
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error")),
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = conn.execute(
|
let result = conn.execute(
|
||||||
"INSERT INTO conversation (creator_id, title) VALUES (?1, ?2)",
|
"INSERT INTO conversation (creator_id, name) VALUES (?1, ?2)",
|
||||||
params![&user_id, &payload.title],
|
params![&user_id, &payload.name],
|
||||||
);
|
);
|
||||||
|
|
||||||
match result {
|
let rows = match result {
|
||||||
Ok(rows) if rows > 0 => (StatusCode::OK, format!("Created conversation {}", payload.title)),
|
Ok(rows) => rows,
|
||||||
Ok(_) => (StatusCode::NOT_FOUND, "not able to create the conversation".to_string() ),
|
Err(err) => {
|
||||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error when creating the conversation : {err}")),
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Error when creating the conversation: {err}"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if rows == 0 {
|
||||||
|
return (
|
||||||
|
StatusCode::NOT_FOUND,
|
||||||
|
"not able to create the conversation".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let conv_id = conn.last_insert_rowid();
|
||||||
|
|
||||||
|
let user_conv_rel = conn.execute(
|
||||||
|
"INSERT INTO conversation_participants (conversation_id, user_id, name)
|
||||||
|
VALUES (?1, ?2, ?3)",
|
||||||
|
params![conv_id, user_id, payload.name],
|
||||||
|
);
|
||||||
|
|
||||||
|
match user_conv_rel {
|
||||||
|
Ok(r) => {
|
||||||
|
return (
|
||||||
|
StatusCode::OK,
|
||||||
|
format!("Created conversation {}", payload.name),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Error when creating the conversation: {err}"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extra logic here (more queries, validations, etc.)
|
||||||
|
|
||||||
|
//(StatusCode::OK, format!("Created conversation {}", payload.name))
|
||||||
|
}
|
||||||
|
|
||||||
|
//FIXME: add title to conv
|
||||||
pub async fn add_user_to_conv(
|
pub async fn add_user_to_conv(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||||
AddUserConversationPayload(payload):AddUserConversationPayload
|
AddUserConversationPayload(payload): AddUserConversationPayload,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
||||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||||
|
|
||||||
let conn = match pool.get(){
|
let mut conn = match pool.get() {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error"))
|
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error")),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut statement = match conn.prepare(
|
let creator_name: Option<String> = match conn
|
||||||
"SELECT 1 FROM conversation WHERE creator_id = ?1 AND id = ?2" ,
|
.query_row(
|
||||||
){
|
"SELECT name FROM conversation WHERE creator_id = ?1 AND id = ?2",
|
||||||
Ok(statement) => statement,
|
params![user_id, payload.conv_id],
|
||||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "prepare failed".to_string())
|
|row| row.get(0),
|
||||||
};
|
)
|
||||||
|
.optional()
|
||||||
match statement.exists(params![user_id, payload.conv_id]) {
|
{
|
||||||
Ok(true) => {
|
Ok(name) => name,
|
||||||
//user is creator
|
//Ok(None) => false,
|
||||||
}
|
|
||||||
Ok(false) => {
|
|
||||||
//user is not the creator
|
|
||||||
return (StatusCode::FORBIDDEN, "Not the creato of the conversation".to_string())
|
|
||||||
}
|
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return(StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string())
|
return (
|
||||||
}
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Creator check failed".to_string(),
|
||||||
}
|
);
|
||||||
|
|
||||||
for target_id in &payload.users {
|
|
||||||
let rows_inserted = match conn.execute(
|
|
||||||
"INSERT INTO conversation_participants (conversation_id, user_id) VALUES (?1, ?2)",
|
|
||||||
params![payload.conv_id, target_id],
|
|
||||||
) {
|
|
||||||
Ok(n) => n,
|
|
||||||
Err(err) => {
|
|
||||||
return (StatusCode::INTERNAL_SERVER_ERROR, format!("Err adding user {}: {}", target_id, err));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if rows_inserted == 0 {
|
let is_creator = creator_name.is_some();
|
||||||
return (StatusCode::NOT_FOUND, format!("Could not add user {}", target_id));
|
|
||||||
|
if !is_creator {
|
||||||
|
return (
|
||||||
|
StatusCode::FORBIDDEN,
|
||||||
|
"Not the creator of the conversation".to_string(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//fix this
|
||||||
|
let existing: HashSet<u32> = {
|
||||||
|
let mut stmt = match conn
|
||||||
|
.prepare("SELECT user_id FROM conversation_participants WHERE conversation_id = ?1")
|
||||||
|
{
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(_) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Prepare participants stmt failed".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match stmt.query_map(params![payload.conv_id], |row| row.get(0)) {
|
||||||
|
Ok(rows) => rows.filter_map(Result::ok).collect(),
|
||||||
|
Err(_) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Query participants failed".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}; // ← stmt dropped HERE
|
||||||
|
|
||||||
|
let payload_users: HashSet<u32> = payload.users.into_iter().collect();
|
||||||
|
|
||||||
|
let to_add: Vec<u32> = payload_users.difference(&existing).copied().collect();
|
||||||
|
|
||||||
|
let to_remove: Vec<u32> = existing.difference(&payload_users).copied().collect();
|
||||||
|
|
||||||
|
let tx = match conn.transaction() {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(_) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Transaction start failed for update conv participants".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for user_id in to_add {
|
||||||
|
if let Err(err) = tx.execute(
|
||||||
|
"INSERT INTO conversation_participants (conversation_id, user_id, name)
|
||||||
|
VALUES (?1, ?2, ?3)",
|
||||||
|
params![payload.conv_id, user_id, creator_name],
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Insert failed for {}: {}", user_id, err),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for user_id in to_remove {
|
||||||
|
if let Err(err) = tx.execute(
|
||||||
|
"DELETE FROM conversation_participants
|
||||||
|
WHERE conversation_id = ?1 AND user_id = ?2",
|
||||||
|
params![payload.conv_id, user_id],
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Delete failed for {}: {}", user_id, err),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(_) = tx.commit() {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Transaction commit failed".to_string(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (StatusCode::OK, "ok".to_string());
|
return (StatusCode::OK, "ok".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct Get
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub async fn get_conv_users(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||||
|
Path(conv_id): Path<i32>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||||
|
|
||||||
|
let conn = match pool.get() {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(err) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Error opening pol connection : {err}"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut stmt = match conn
|
||||||
|
.prepare("SELECT conversation_id, name FROM conversation_participants WHERE user_id = ?1")
|
||||||
|
{
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Prepare failed: {}", e),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//fix this
|
||||||
|
let existing: HashSet<u32> = {
|
||||||
|
let mut stmt = match conn
|
||||||
|
.prepare("SELECT user_id FROM conversation_participants WHERE conversation_id = ?1")
|
||||||
|
{
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(_) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Prepare participants stmt failed".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match stmt.query_map(params![conv_id], |row| row.get(0)) {
|
||||||
|
Ok(rows) => rows.filter_map(Result::ok).collect(),
|
||||||
|
Err(_) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Query participants failed".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}; // ← stmt dropped HERE
|
||||||
|
|
||||||
|
let present: Vec<u32> = existing.into_iter().collect();
|
||||||
|
|
||||||
|
match serde_json::to_string(&present) {
|
||||||
|
Ok(json) => (StatusCode::OK, json),
|
||||||
|
Err(e) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Serialization failed: {}", e),
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_message(
|
pub async fn send_message(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||||
SendMessagePayload(payload):SendMessagePayload
|
SendMessagePayload(payload): SendMessagePayload,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
//TODO: make sur the convid is valid
|
||||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||||
|
|
||||||
let conn = match pool.get() {
|
let conn = match pool.get() {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error"))
|
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error")),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut statement = match conn.prepare(
|
let mut statement = match conn.prepare(
|
||||||
"SELECT 1 FROM conversation_participants WHERE user_id = ?1 AND conversation_id = ?2",
|
"SELECT 1 FROM conversation_participants WHERE user_id = ?1 AND conversation_id = ?2",
|
||||||
) {
|
) {
|
||||||
Ok(statement) => statement,
|
Ok(statement) => statement,
|
||||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "prepare failed".to_string())
|
Err(_) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"prepare failed".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match statement.exists(params![user_id, payload.conv_id]) {
|
match statement.exists(params![user_id, payload.conv_id]) {
|
||||||
@@ -128,21 +301,38 @@ pub async fn send_message(
|
|||||||
}
|
}
|
||||||
Ok(false) => {
|
Ok(false) => {
|
||||||
// early exit: not part of the conversation
|
// early exit: not part of the conversation
|
||||||
return (StatusCode::FORBIDDEN, "Not part of the conversation".to_string());
|
return (
|
||||||
|
StatusCode::FORBIDDEN,
|
||||||
|
"Not part of the conversation".to_string(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// query failed
|
// query failed
|
||||||
return (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string());
|
return (
|
||||||
}
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
}
|
"Query failed".to_string(),
|
||||||
|
|
||||||
let result = conn.execute(
|
|
||||||
"INSERT INTO message (sender_id, content, conversation_id) VALUES (?1, ?2, ?3)",
|
|
||||||
params![&user_id, &payload.message, &payload.conv_id],
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (message_id, sent_at): (i64, String) = match conn.query_row(
|
||||||
|
"INSERT INTO message (sender_id, content, conversation_id)
|
||||||
|
VALUES (?1, ?2, ?3)
|
||||||
|
RETURNING id, sent_at",
|
||||||
|
params![user_id, payload.message, payload.conv_id],
|
||||||
|
|row| Ok((row.get::<_, i64>(0)?, row.get::<_, String>(1)?)),
|
||||||
|
) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(err) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("DB insert failed: {err}"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//let message_id = conn.last_insert_rowid();
|
||||||
|
// FIXME: add sent_at and message id in the response.
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(rows) if rows > 0 => {
|
|
||||||
// --- send to conversation participants ---
|
// --- send to conversation participants ---
|
||||||
let mut stmt_participants = conn
|
let mut stmt_participants = conn
|
||||||
.prepare("SELECT user_id FROM conversation_participants WHERE conversation_id = ?1")
|
.prepare("SELECT user_id FROM conversation_participants WHERE conversation_id = ?1")
|
||||||
@@ -156,28 +346,31 @@ pub async fn send_message(
|
|||||||
|
|
||||||
if let Some(hotel_users) = state.ws_map.get(&hotel_id) {
|
if let Some(hotel_users) = state.ws_map.get(&hotel_id) {
|
||||||
let update_msg = serde_json::json!({
|
let update_msg = serde_json::json!({
|
||||||
"event-type": "chat-message",
|
"event_type": "chat_message",
|
||||||
"conv_id": payload.conv_id,
|
"conv_id": payload.conv_id,
|
||||||
"sender": user_id,
|
"sender_id": user_id,
|
||||||
"content": payload.message,
|
"content": payload.message,
|
||||||
|
"id": message_id,
|
||||||
|
"sent_at": sent_at,
|
||||||
})
|
})
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
for uid in &participant_ids {
|
for uid in &participant_ids {
|
||||||
if let Some(sender) = hotel_users.get(&uid) {
|
if let Some(sender) = hotel_users.get(uid) {
|
||||||
let _ = sender.send(axum::extract::ws::Message::Text(update_msg.clone().into()));
|
let _ = sender.send(axum::extract::ws::Message::Text(update_msg.clone().into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(StatusCode::OK, format!("sent message: {}, to users:{:?}", payload.message, participant_ids))
|
(
|
||||||
|
StatusCode::OK,
|
||||||
|
format!(
|
||||||
|
"sent message: {}, to users:{:?}",
|
||||||
|
payload.message, participant_ids
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Ok(_) => (StatusCode::NOT_FOUND, "Conversation not found".to_string()),
|
//Ok(_) => (StatusCode::NOT_FOUND, "Conversation not found".to_string()),
|
||||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error from DB: {err}")),
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
struct Message {
|
struct Message {
|
||||||
@@ -187,16 +380,15 @@ struct Message {
|
|||||||
sent_at: String,
|
sent_at: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn get_message(
|
pub async fn get_message(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||||
GetMessagesPayload(payload):GetMessagesPayload
|
GetMessagesPayload(payload): GetMessagesPayload,
|
||||||
) -> Result<impl IntoResponse, (StatusCode, String)> {
|
) -> Result<impl IntoResponse, (StatusCode, String)> {
|
||||||
|
|
||||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||||
|
|
||||||
let conn = pool.get()
|
let conn = pool
|
||||||
|
.get()
|
||||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Pool error".to_string()))?;
|
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Pool error".to_string()))?;
|
||||||
|
|
||||||
let from_time = match payload.timestamp.as_deref() {
|
let from_time = match payload.timestamp.as_deref() {
|
||||||
@@ -204,82 +396,115 @@ pub async fn get_message(
|
|||||||
Some(ts) => ts,
|
Some(ts) => ts,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut stmt = conn.prepare(
|
let mut stmt = conn
|
||||||
|
.prepare(
|
||||||
"SELECT id, sender_id, content, sent_at
|
"SELECT id, sender_id, content, sent_at
|
||||||
FROM message
|
FROM message
|
||||||
WHERE conversation_id = ?1
|
WHERE conversation_id = ?1
|
||||||
AND sent_at > ?2
|
AND sent_at > ?2
|
||||||
ORDER BY sent_at DESC
|
ORDER BY sent_at DESC
|
||||||
LIMIT 50"
|
LIMIT 50",
|
||||||
).map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Prepare failed".to_string()))?;
|
)
|
||||||
|
.map_err(|_| {
|
||||||
|
(
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Prepare failed".to_string(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let messages = stmt
|
||||||
let messages = stmt.query_map(
|
.query_map(params![payload.conv_id, from_time], |row| {
|
||||||
params![payload.conv_id, from_time],
|
|
||||||
|row| {
|
|
||||||
Ok(Message {
|
Ok(Message {
|
||||||
id: row.get(0)?,
|
id: row.get(0)?,
|
||||||
sender_id: row.get(1)?,
|
sender_id: row.get(1)?,
|
||||||
content: row.get(2)?,
|
content: row.get(2)?,
|
||||||
sent_at: row.get(3)?,
|
sent_at: row.get(3)?,
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
|
.map_err(|_| {
|
||||||
|
(
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Query failed".to_string(),
|
||||||
)
|
)
|
||||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string()))?
|
})?
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Collect failed".to_string()))?;
|
.map_err(|_| {
|
||||||
|
(
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Collect failed".to_string(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let response = serde_json::to_string(&messages)
|
let response = serde_json::to_string(&messages)
|
||||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Serialisation failed"));
|
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Serialisation failed"));
|
||||||
|
|
||||||
Ok((StatusCode::OK, response))
|
Ok((StatusCode::OK, response))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct User {
|
struct User {
|
||||||
id: i32,
|
id: i32,
|
||||||
username: String,
|
username: String,
|
||||||
display_name: String,
|
//display_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn get_hotel_users(
|
pub async fn get_hotel_users(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
AuthClaims { hotel_id, .. }: AuthClaims,
|
AuthClaims { hotel_id, .. }: AuthClaims,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
let conn = match state.logs_pool.get() {
|
let conn = match state.logs_pool.get() {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "DB connection error".to_string()),
|
Err(_) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"DB connection error".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut stmt = match conn.prepare(
|
let mut stmt =
|
||||||
"SELECT id, username, displayname FROM users WHERE hotel_id = ?1",
|
match conn.prepare("SELECT user_id, username FROM hotel_user_link WHERE hotel_id = ?1") {
|
||||||
) {
|
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Prepare failed: {}", e)),
|
Err(e) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Prepare failed: {}", e),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let users_iter = match stmt.query_map(params![hotel_id], |row| {
|
let users_iter = match stmt.query_map(params![hotel_id], |row| {
|
||||||
Ok(User {
|
Ok(User {
|
||||||
id: row.get(0)?,
|
id: row.get(0)?,
|
||||||
username: row.get(1)?,
|
username: row.get(1)?,
|
||||||
display_name: row.get(2)?,
|
//display_name: row.get(2)?,
|
||||||
})
|
})
|
||||||
}) {
|
}) {
|
||||||
Ok(iter) => iter,
|
Ok(iter) => iter,
|
||||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Query failed: {}", e)),
|
Err(e) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Query failed: {}", e),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let users: Vec<User> = match users_iter.collect::<Result<Vec<_>, _>>() {
|
let users: Vec<User> = match users_iter.collect::<Result<Vec<_>, _>>() {
|
||||||
Ok(u) => u,
|
Ok(u) => u,
|
||||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Collect failed: {}", e)),
|
Err(e) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Collect failed: {}", e),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match serde_json::to_string(&users) {
|
match serde_json::to_string(&users) {
|
||||||
Ok(json) => (StatusCode::OK, json),
|
Ok(json) => (StatusCode::OK, json),
|
||||||
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Serialization failed: {}", e)),
|
Err(e) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Serialization failed: {}", e),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,71 +514,74 @@ struct Conversation {
|
|||||||
title: String,
|
title: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FIXME: allow null conv name ? default to persons name
|
||||||
pub async fn get_convs(
|
pub async fn get_convs(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
//Path((item_name, item_amount)): Path<(String, i32)>,
|
//Path((item_name, item_amount)): Path<(String, i32)>,
|
||||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
||||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||||
|
|
||||||
let conn = match pool.get() {
|
let conn = match pool.get() {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let body = json!({ "error": format!("Pool error: {}", err) });
|
return (
|
||||||
return (StatusCode::INTERNAL_SERVER_ERROR, Json(body));
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Pool error: {err}"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut stmt = match conn.prepare(
|
let mut stmt = match conn
|
||||||
"SELECT conversation_id, name FROM conversation_participants WHERE user_id = ?1",
|
.prepare("SELECT conversation_id, name FROM conversation_participants WHERE user_id = ?1")
|
||||||
) {
|
{
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let body = json!({ "error": format!("Prepare failed: {}", e) });
|
return (
|
||||||
return (StatusCode::INTERNAL_SERVER_ERROR, Json(body) )
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Prepare failed: {}", e),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let rows = match stmt.query_map(params![user_id], |row| {
|
let rows = match stmt.query_map(params![user_id], |row| {
|
||||||
let conversation_id: i32 = row.get(0)?;
|
let conversation_id: i32 = row.get(0)?;
|
||||||
let name: String = row.get(1)?;
|
let name: String = row.get(1)?;
|
||||||
Ok((conversation_id, name))
|
Ok(Conversation {
|
||||||
|
id: row.get(0)?,
|
||||||
|
title: row.get(1)?,
|
||||||
|
})
|
||||||
}) {
|
}) {
|
||||||
Ok(rows) => rows,
|
Ok(rows) => rows,
|
||||||
//Ok(_) => {}, IMPLEMENT NO CONV ?
|
//Ok(_) => {}, IMPLEMENT NO CONV ?
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let body = json!({ "error": format!("Query failed: {}", e) });
|
return (
|
||||||
return (StatusCode::INTERNAL_SERVER_ERROR, Json(body));
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Query failed: {}", e),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let convs: Vec<Conversation> = match rows.collect::<Result<Vec<_>, _>>() {
|
||||||
let mut map = HashMap::new();
|
Ok(u) => u,
|
||||||
|
|
||||||
// ✅ Iterate through the row results
|
|
||||||
for row_result in rows {
|
|
||||||
match row_result {
|
|
||||||
Ok((id, name)) => {
|
|
||||||
map.insert(id, name);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let body = json!({ "error": format!("Row parsing failed: {}", e) });
|
return (
|
||||||
return (StatusCode::INTERNAL_SERVER_ERROR, Json(body));
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Collect failed: {}", e),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, Json("error".to_string())));
|
||||||
|
|
||||||
|
match serde_json::to_string(&convs) {
|
||||||
|
Ok(json) => (StatusCode::OK, json),
|
||||||
|
Err(e) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Serialization failed: {}", e),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let convs_string = serde_json::to_string(&map)
|
|
||||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, Json("error".to_string())));
|
|
||||||
|
|
||||||
let conv_map_json = to_value(map).unwrap();
|
|
||||||
(StatusCode::OK, Json(conv_map_json))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub async fn get_convs(
|
pub async fn get_convs(
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
|
||||||
|
|
||||||
mod extractor;
|
mod extractor;
|
||||||
mod handlers;
|
mod handlers;
|
||||||
@@ -1,25 +1,15 @@
|
|||||||
use axum::{
|
use axum::{Router, routing::get, routing::post, routing::put};
|
||||||
Router,
|
|
||||||
routing::put,
|
|
||||||
routing::post,
|
|
||||||
routing::get,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::utils::db_pool::AppState;
|
|
||||||
use crate::chat::handlers::*;
|
use crate::chat::handlers::*;
|
||||||
|
use crate::utils::db_pool::AppState;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn chat_routes() -> Router<AppState> {
|
pub fn chat_routes() -> Router<AppState> {
|
||||||
|
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/create_conversation", post(create_conversation))
|
.route("/create_conversation", post(create_conversation))
|
||||||
.route("/add_users_conv", put(add_user_to_conv))
|
.route("/add_users_conv", put(add_user_to_conv))
|
||||||
.route("/send_message", post(send_message))
|
.route("/send_message", post(send_message))
|
||||||
.route("/get_conv", get(get_convs))
|
.route("/get_conv", post(get_convs))
|
||||||
.route("/get_message", get(get_message))
|
.route("/get_message", post(get_message))
|
||||||
.route("/hotel_users", get(get_hotel_users))
|
.route("/hotel_users", post(get_hotel_users))
|
||||||
|
.route("/get_conv_users/{conv_id}", post(get_conv_users))
|
||||||
}
|
}
|
||||||
@@ -1,36 +1,48 @@
|
|||||||
|
|
||||||
use argon2::Params;
|
use argon2::Params;
|
||||||
use axum::{extract::{ws::{close_code::STATUS, Message}, Path, State}, http::StatusCode, response::IntoResponse};
|
use axum::{
|
||||||
|
extract::{
|
||||||
|
Path, State,
|
||||||
|
ws::{Message, close_code::STATUS},
|
||||||
|
},
|
||||||
|
http::StatusCode,
|
||||||
|
response::IntoResponse,
|
||||||
|
};
|
||||||
use rusqlite::params;
|
use rusqlite::params;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use crate::utils::{auth::AuthClaims, db_pool::AppState};
|
use crate::utils::{auth::AuthClaims, db_pool::AppState};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn create_inventory_item(
|
pub async fn create_inventory_item(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
Path((item_name, item_amount)): Path<(String, i32)>,
|
Path((item_name, item_amount)): Path<(String, i32)>,
|
||||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
||||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||||
|
|
||||||
let conn = match pool.get() {
|
let conn = match pool.get() {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("couldn't open the connection"))
|
Err(err) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("couldn't open the connection"),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = conn.execute(
|
let result = conn.execute(
|
||||||
"INSERT INTO inventory (item_name, amount, user_id) VALUES (?1, ?2, ?3)",
|
"INSERT INTO inventory (item_name, amount, user_id) VALUES (?1, ?2, ?3)",
|
||||||
params![&item_name,&item_amount,&user_id]
|
params![&item_name, &item_amount, &user_id],
|
||||||
);
|
);
|
||||||
match result {
|
match result {
|
||||||
Ok(rows) => (StatusCode::OK, format!("inserted item {item_name}, with {item_amount} amount")),
|
Ok(rows) => (
|
||||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("couldn't add the new item, err: {}", err ))
|
StatusCode::OK,
|
||||||
|
format!("inserted item {item_name}, with {item_amount} amount"),
|
||||||
|
),
|
||||||
|
Err(err) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("couldn't add the new item, err: {}", err),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +60,6 @@ pub async fn update_inventory_item(
|
|||||||
Path((item_id, item_amount)): Path<(i32, i32)>,
|
Path((item_id, item_amount)): Path<(i32, i32)>,
|
||||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
||||||
//TODO: make better error handling :
|
//TODO: make better error handling :
|
||||||
// if wrong param collumn targeted,
|
// if wrong param collumn targeted,
|
||||||
// if missing path param
|
// if missing path param
|
||||||
@@ -57,7 +68,12 @@ pub async fn update_inventory_item(
|
|||||||
|
|
||||||
let conn = match pool.get() {
|
let conn = match pool.get() {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error: {err}")),
|
Err(err) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Pool error: {err}"),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result: Result<String, rusqlite::Error> = conn.query_row(
|
let result: Result<String, rusqlite::Error> = conn.query_row(
|
||||||
@@ -74,12 +90,34 @@ pub async fn update_inventory_item(
|
|||||||
){
|
){
|
||||||
return (StatusCode::INTERNAL_SERVER_ERROR, format!("failed to update inventory history"));
|
return (StatusCode::INTERNAL_SERVER_ERROR, format!("failed to update inventory history"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(hotel_users) = state.ws_map.get(&hotel_id) {
|
||||||
|
let update_msg = json!({
|
||||||
|
"event_type": "item_update",
|
||||||
|
"item_id": item_id,
|
||||||
|
"number": item_amount,
|
||||||
|
"updated_by": user_id,
|
||||||
|
})
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
for entry in hotel_users.iter() {
|
||||||
|
let sender = entry.value();
|
||||||
|
// ignore errors (client disconnected)
|
||||||
|
let _ = sender.send(Message::Text(update_msg.clone().into()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(StatusCode::OK, format!("updated item history"))
|
(StatusCode::OK, format!("updated item history"))
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(_) => (StatusCode::NOT_FOUND, "No room found".to_string()),
|
Ok(_) => (
|
||||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error from DB: {err}")),
|
StatusCode::NOT_FOUND,
|
||||||
|
"No item found, err : {_}".to_string(),
|
||||||
|
),
|
||||||
|
Err(err) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Error from DB: {err}"),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -89,10 +127,8 @@ pub async fn update_inventory_item(
|
|||||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("error updating the item with id :{} with amount: {}", item_id, item_amount))
|
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("error updating the item with id :{} with amount: {}", item_id, item_amount))
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub async fn get_inventory_item(
|
pub async fn get_inventory_item(
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||||
@@ -104,9 +140,15 @@ pub async fn get_inventory_item(
|
|||||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Pool error".to_string()),
|
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Pool error".to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut stmt = match conn.prepare("SELECT id, amount, item_name, user_id FROM inventory") {
|
let mut stmt =
|
||||||
|
match conn.prepare("SELECT id, amount, item_name, user_id, updated_at FROM inventory") {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Statement error".to_string()),
|
Err(_) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Statement error".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut query_result = match stmt.query([]) {
|
let mut query_result = match stmt.query([]) {
|
||||||
@@ -120,7 +162,7 @@ pub async fn get_inventory_item(
|
|||||||
let item = InventoryItems {
|
let item = InventoryItems {
|
||||||
id: row.get("id").unwrap_or_default(),
|
id: row.get("id").unwrap_or_default(),
|
||||||
amount: row.get("amount").unwrap_or_default(),
|
amount: row.get("amount").unwrap_or_default(),
|
||||||
name: row.get("name").unwrap_or_default(),
|
name: row.get("item_name").unwrap_or_default(),
|
||||||
user_id: row.get("user_id").unwrap_or_default(),
|
user_id: row.get("user_id").unwrap_or_default(),
|
||||||
updated_at: row.get("updated_at").unwrap_or_default(),
|
updated_at: row.get("updated_at").unwrap_or_default(),
|
||||||
};
|
};
|
||||||
@@ -130,7 +172,12 @@ pub async fn get_inventory_item(
|
|||||||
// Serialize to JSON
|
// Serialize to JSON
|
||||||
let json = match serde_json::to_string(&items) {
|
let json = match serde_json::to_string(&items) {
|
||||||
Ok(j) => j,
|
Ok(j) => j,
|
||||||
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, "Serialization error".to_string()),
|
Err(_) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Serialization error".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(StatusCode::OK, json)
|
(StatusCode::OK, json)
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
routing::{get, put, post},
|
|
||||||
Router,
|
Router,
|
||||||
|
routing::{get, post, put},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{inventory::handler::*, utils::db_pool::AppState};
|
use crate::{inventory::handler::*, utils::db_pool::AppState};
|
||||||
|
|
||||||
pub fn inventory_routes() -> Router<AppState> {
|
pub fn inventory_routes() -> Router<AppState> {
|
||||||
|
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/update_item/{item_id}/{item_amount}", put(update_inventory_item))
|
.route(
|
||||||
.route("/add_item/{item_name}/{item_amount}", post(create_inventory_item))
|
"/update_item/{item_id}/{item_amount}",
|
||||||
|
put(update_inventory_item),
|
||||||
|
)
|
||||||
|
.route(
|
||||||
|
"/add_item/{item_name}/{item_amount}",
|
||||||
|
post(create_inventory_item),
|
||||||
|
)
|
||||||
.route("/get_item/", get(get_inventory_item))
|
.route("/get_item/", get(get_inventory_item))
|
||||||
}
|
}
|
||||||
11
src/lib.rs
11
src/lib.rs
@@ -1,8 +1,7 @@
|
|||||||
#[allow(unused_imports)]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
|
|
||||||
pub mod utils;
|
|
||||||
pub mod routes;
|
|
||||||
pub mod rooms;
|
|
||||||
pub mod chat;
|
pub mod chat;
|
||||||
pub mod inventory;
|
pub mod inventory;
|
||||||
|
pub mod rooms;
|
||||||
|
pub mod routes;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub mod utils;
|
||||||
|
|||||||
56
src/main.rs
56
src/main.rs
@@ -1,30 +1,37 @@
|
|||||||
use axum::serve;
|
|
||||||
use axum::Extension;
|
use axum::Extension;
|
||||||
use axum::extract::{ws::{Message, WebSocket, WebSocketUpgrade}, State};
|
use axum::extract::{
|
||||||
|
State,
|
||||||
|
ws::{Message, WebSocket, WebSocketUpgrade},
|
||||||
|
};
|
||||||
|
use axum::serve;
|
||||||
use jsonwebtoken::{DecodingKey, EncodingKey};
|
use jsonwebtoken::{DecodingKey, EncodingKey};
|
||||||
|
use reqwest::header::AUTHORIZATION;
|
||||||
|
use reqwest::header::CONTENT_TYPE;
|
||||||
|
use reqwest::header::USER_AGENT;
|
||||||
|
|
||||||
|
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use tokio::sync::mpsc;
|
|
||||||
|
|
||||||
use reqwest::Client;
|
use crate::utils::auth::JwtKeys;
|
||||||
|
use crate::utils::db_pool::{AppState, HotelPool};
|
||||||
|
use routes::create_router;
|
||||||
|
|
||||||
|
use dotenvy::dotenv;
|
||||||
|
use std::env;
|
||||||
|
//use tower_http::cors::Origin;
|
||||||
|
use axum::http::{HeaderValue, Method};
|
||||||
|
use tower_http::cors::{Any, CorsLayer};
|
||||||
|
|
||||||
mod utils;
|
|
||||||
mod routes;
|
|
||||||
mod rooms;
|
|
||||||
mod chat;
|
mod chat;
|
||||||
mod inventory;
|
mod inventory;
|
||||||
use r2d2::{Pool};
|
mod rooms;
|
||||||
use r2d2_sqlite::SqliteConnectionManager;
|
mod routes;
|
||||||
|
mod utils;
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
|
use r2d2::Pool;
|
||||||
|
use r2d2_sqlite::SqliteConnectionManager;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::utils::db_pool::{HotelPool,AppState};
|
|
||||||
use routes::create_router;
|
|
||||||
use crate::utils::auth::JwtKeys;
|
|
||||||
|
|
||||||
use std::env;
|
|
||||||
use dotenvy::dotenv;
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn notify_discord(msg: &str) -> Result<(), reqwest::Error> {
|
pub async fn notify_discord(msg: &str) -> Result<(), reqwest::Error> {
|
||||||
let payload = serde_json::json!({
|
let payload = serde_json::json!({
|
||||||
"content": msg
|
"content": msg
|
||||||
@@ -39,10 +46,8 @@ pub async fn notify_discord(msg: &str) -> Result<(), reqwest::Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[tokio::main(flavor = "multi_thread", worker_threads = 8)]
|
#[tokio::main(flavor = "multi_thread", worker_threads = 8)]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
|
|
||||||
std::panic::set_hook(Box::new(|info| {
|
std::panic::set_hook(Box::new(|info| {
|
||||||
@@ -63,7 +68,7 @@ std::panic::set_hook(Box::new(|info| {
|
|||||||
//panic!("crash-test");
|
//panic!("crash-test");
|
||||||
|
|
||||||
let hotel_pools = HotelPool::new();
|
let hotel_pools = HotelPool::new();
|
||||||
let logs_manager = SqliteConnectionManager::file("db/auth.sqlite");
|
let logs_manager = SqliteConnectionManager::file("db/auth_copy_2.sqlite");
|
||||||
let logs_pool = Pool::builder()
|
let logs_pool = Pool::builder()
|
||||||
.max_size(5)
|
.max_size(5)
|
||||||
.build(logs_manager)
|
.build(logs_manager)
|
||||||
@@ -87,12 +92,15 @@ std::panic::set_hook(Box::new(|info| {
|
|||||||
decoding: DecodingKey::from_secret(jwt_secret.as_ref()),
|
decoding: DecodingKey::from_secret(jwt_secret.as_ref()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let allowed_origins = vec!["http://82.66.253.209", "http://localhost:5173"];
|
||||||
|
|
||||||
|
let cors = CorsLayer::very_permissive()
|
||||||
|
.allow_credentials(true)
|
||||||
|
.allow_methods([Method::GET, Method::POST, Method::PUT, Method::OPTIONS])
|
||||||
|
.allow_headers([CONTENT_TYPE, AUTHORIZATION, USER_AGENT]);
|
||||||
|
let app = create_router(state).layer(Extension(jwt_keys)).layer(cors);
|
||||||
|
|
||||||
let app = create_router(state)
|
let listener = TcpListener::bind("0.0.0.0:7080").await?;
|
||||||
.layer(Extension(jwt_keys));
|
|
||||||
|
|
||||||
let listener = TcpListener::bind("0.0.0.0:8080").await?;
|
|
||||||
serve(listener, app).into_future().await?;
|
serve(listener, app).into_future().await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
#[derive(Deserialize, Debug)]
|
|
||||||
pub struct GetMessagesValues {
|
|
||||||
pub conv_id: u32,
|
|
||||||
pub timestamp: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn get_message(
|
|
||||||
State(state): State<AppState>,
|
|
||||||
AuthClaims { user_id, hotel_id, username }: AuthClaims,
|
|
||||||
Json(payload): Json<GetMessagesValues>, // ✅ no custom payload wrapper
|
|
||||||
) -> Result<impl IntoResponse, (StatusCode, String)> {
|
|
||||||
|
|
||||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
|
||||||
|
|
||||||
let conn = pool.get()
|
|
||||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Pool error".to_string()))?;
|
|
||||||
|
|
||||||
let from_time = match payload.timestamp.as_deref() {
|
|
||||||
Some("0") | None => "1970-01-01 00:00:00",
|
|
||||||
Some(ts) => ts,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut stmt = conn.prepare(
|
|
||||||
"SELECT id, sender_id, content, sent_at
|
|
||||||
FROM message
|
|
||||||
WHERE conversation_id = ?1
|
|
||||||
AND sent_at > ?2
|
|
||||||
ORDER BY sent_at DESC
|
|
||||||
LIMIT 50"
|
|
||||||
).map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Prepare failed".to_string()))?;
|
|
||||||
|
|
||||||
let messages = stmt.query_map(
|
|
||||||
params![payload.conv_id, from_time],
|
|
||||||
|row| {
|
|
||||||
Ok(Message {
|
|
||||||
id: row.get(0)?,
|
|
||||||
sender_id: row.get(1)?,
|
|
||||||
content: row.get(2)?,
|
|
||||||
sent_at: row.get(3)?,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string()))?
|
|
||||||
.collect::<Result<Vec<_>, _>>()
|
|
||||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Collect failed".to_string()))?;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
extract::{Request, FromRequest, Path},
|
|
||||||
body::{Body},
|
|
||||||
|
|
||||||
http::StatusCode,
|
|
||||||
Json, Router,
|
Json, Router,
|
||||||
|
body::Body,
|
||||||
|
extract::{FromRequest, Path, Request},
|
||||||
|
http::StatusCode,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@@ -16,7 +15,8 @@ pub struct UpdateRoomPayload(pub UpdateRoomValues);
|
|||||||
|
|
||||||
//#[async_trait]
|
//#[async_trait]
|
||||||
impl<S> FromRequest<S> for UpdateRoomPayload
|
impl<S> FromRequest<S> for UpdateRoomPayload
|
||||||
where S: Send + Sync,
|
where
|
||||||
|
S: Send + Sync,
|
||||||
{
|
{
|
||||||
type Rejection = (StatusCode, String);
|
type Rejection = (StatusCode, String);
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ where S: Send + Sync,
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RoomIdValue {
|
pub struct RoomIdValue {
|
||||||
pub room_id: i32
|
pub room_id: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type RoomIdPath = Path<i32>;
|
pub type RoomIdPath = Path<i32>;
|
||||||
@@ -1,22 +1,20 @@
|
|||||||
use axum::{Json, extract::Path, extract::State };
|
|
||||||
use axum::response::IntoResponse;
|
|
||||||
use axum::http::StatusCode;
|
|
||||||
use axum::extract::ws::Message;
|
use axum::extract::ws::Message;
|
||||||
|
use axum::http::StatusCode;
|
||||||
|
use axum::response::IntoResponse;
|
||||||
|
use axum::{Json, extract::Path, extract::State};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::rooms::extractor::UpdateRoomPayload;
|
use crate::rooms::extractor::UpdateRoomPayload;
|
||||||
//use crate::utils::db_pool::*;
|
//use crate::utils::db_pool::*;
|
||||||
use crate::utils::auth::AuthClaims;
|
use crate::utils::auth::AuthClaims;
|
||||||
use crate::utils::db_pool::{HotelPool,AppState};
|
use crate::utils::db_pool::{AppState, HotelPool};
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
use r2d2::{Pool};
|
|
||||||
use r2d2_sqlite::SqliteConnectionManager;
|
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
|
use r2d2::Pool;
|
||||||
|
use r2d2_sqlite::SqliteConnectionManager;
|
||||||
use rusqlite::params;
|
use rusqlite::params;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
|
||||||
pub async fn hello_rooms() -> String {
|
pub async fn hello_rooms() -> String {
|
||||||
"hello from rooms".to_string()
|
"hello from rooms".to_string()
|
||||||
@@ -28,11 +26,15 @@ pub async fn fake_db_update(
|
|||||||
Path(room_id): Path<i32>,
|
Path(room_id): Path<i32>,
|
||||||
UpdateRoomPayload(payload): UpdateRoomPayload,
|
UpdateRoomPayload(payload): UpdateRoomPayload,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
||||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||||
let conn = match pool.get() {
|
let conn = match pool.get() {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error: {err}")),
|
Err(err) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Pool error: {err}"),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = conn.execute(
|
let result = conn.execute(
|
||||||
@@ -41,9 +43,15 @@ pub async fn fake_db_update(
|
|||||||
);
|
);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(rows) if rows > 0 => (StatusCode::OK, format!("Updated room {room_id} in hotel {}", hotel_id)),
|
Ok(rows) if rows > 0 => (
|
||||||
|
StatusCode::OK,
|
||||||
|
format!("Updated room {room_id} in hotel {}", hotel_id),
|
||||||
|
),
|
||||||
Ok(_) => (StatusCode::NOT_FOUND, "No room found".to_string()),
|
Ok(_) => (StatusCode::NOT_FOUND, "No room found".to_string()),
|
||||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("DB error: {err}")),
|
Err(err) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("DB error: {err}"),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +61,6 @@ pub async fn clean_db_update(
|
|||||||
AuthClaims { user_id, hotel_id }: AuthClaims,
|
AuthClaims { user_id, hotel_id }: AuthClaims,
|
||||||
UpdateRoomPayload(payload): UpdateRoomPayload,
|
UpdateRoomPayload(payload): UpdateRoomPayload,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
||||||
//TODO: make better error handling :
|
//TODO: make better error handling :
|
||||||
// if wrong param collumn targeted,
|
// if wrong param collumn targeted,
|
||||||
// if missing path param
|
// if missing path param
|
||||||
@@ -62,7 +69,12 @@ pub async fn clean_db_update(
|
|||||||
|
|
||||||
let conn = match pool.get() {
|
let conn = match pool.get() {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error: {err}")),
|
Err(err) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Pool error: {err}"),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result: Result<String, rusqlite::Error> = conn.query_row(
|
let result: Result<String, rusqlite::Error> = conn.query_row(
|
||||||
@@ -71,7 +83,6 @@ pub async fn clean_db_update(
|
|||||||
|row| row.get(0),
|
|row| row.get(0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(room_number) => {
|
Ok(room_number) => {
|
||||||
// --- broadcast to all WS clients in the hotel ---
|
// --- broadcast to all WS clients in the hotel ---
|
||||||
@@ -79,11 +90,14 @@ pub async fn clean_db_update(
|
|||||||
"INSERT INTO room_history (room_id, room_number, status) VALUES (?1, ?2, ?3)",
|
"INSERT INTO room_history (room_id, room_number, status) VALUES (?1, ?2, ?3)",
|
||||||
params![&room_id, &room_number, &payload.status],
|
params![&room_id, &room_number, &payload.status],
|
||||||
) {
|
) {
|
||||||
return (StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to insert history: {err}"));
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Failed to insert history: {err}"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if let Some(hotel_users) = state.ws_map.get(&hotel_id) {
|
if let Some(hotel_users) = state.ws_map.get(&hotel_id) {
|
||||||
let update_msg = json!({
|
let update_msg = json!({
|
||||||
"event-type": "room-update",
|
"event_type": "room_update",
|
||||||
"room_id": room_id,
|
"room_id": room_id,
|
||||||
"status": payload.status,
|
"status": payload.status,
|
||||||
"updated_by": user_id,
|
"updated_by": user_id,
|
||||||
@@ -97,10 +111,19 @@ pub async fn clean_db_update(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(StatusCode::OK, format!("updated room {room_id} in hotel {hotel_id}, with status: {}", payload.status))
|
(
|
||||||
|
StatusCode::OK,
|
||||||
|
format!(
|
||||||
|
"updated room {room_id} in hotel {hotel_id}, with status: {}",
|
||||||
|
payload.status
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Ok(_) => (StatusCode::NOT_FOUND, "No room found".to_string()),
|
Ok(_) => (StatusCode::NOT_FOUND, "No room found".to_string()),
|
||||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error from DB: {err}")),
|
Err(err) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Error from DB: {err}"),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,50 +138,65 @@ pub async fn get_all_rooms(
|
|||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
AuthClaims { hotel_id, .. }: AuthClaims,
|
AuthClaims { hotel_id, .. }: AuthClaims,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
||||||
let pool = state.hotel_pools.get_pool(hotel_id);
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||||
|
|
||||||
let conn = match pool.get() {
|
let conn = match pool.get() {
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(err) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Pool error: {err}")),
|
Err(err) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Pool error: {err}"),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut stmt = match conn.prepare(
|
let mut stmt = match conn.prepare("SELECT id, number, status FROM rooms ") {
|
||||||
"SELECT id, number, status FROM rooms ",
|
|
||||||
) {
|
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Prepare failed: {}", e)),
|
Err(e) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Prepare failed: {}", e),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let room_iter = match stmt.query_map(
|
let room_iter = match stmt.query_map(params![], |row| {
|
||||||
params![],|row| {
|
|
||||||
Ok(Room {
|
Ok(Room {
|
||||||
id: row.get(0)?,
|
id: row.get(0)?,
|
||||||
number: row.get(1)?,
|
number: row.get(1)?,
|
||||||
status: row.get(2)?,
|
status: row.get(2)?,
|
||||||
})
|
})
|
||||||
}
|
}) {
|
||||||
) {
|
|
||||||
Ok(iter) => iter,
|
Ok(iter) => iter,
|
||||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Query failed: {}", e)),
|
Err(e) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Query failed: {}", e),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let rooms: Vec<Room> = match room_iter.collect::<Result<Vec<_>, _>>() {
|
let rooms: Vec<Room> = match room_iter.collect::<Result<Vec<_>, _>>() {
|
||||||
Ok(u) => u,
|
Ok(u) => u,
|
||||||
Err(e) => return (StatusCode::INTERNAL_SERVER_ERROR, format!("Collect failed: {}", e)),
|
Err(e) => {
|
||||||
|
return (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Collect failed: {}", e),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match serde_json::to_string(&rooms) {
|
match serde_json::to_string(&rooms) {
|
||||||
Ok(json) => (StatusCode::OK, json),
|
Ok(json) => (StatusCode::OK, json),
|
||||||
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Serialization failed: {}", e)),
|
Err(e) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("Serialization failed: {}", e),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct RoomRequest {
|
struct RoomRequest {
|
||||||
item_id: i32,
|
item_id: i32,
|
||||||
item_amount: i32,
|
item_amount: i32,
|
||||||
token: String,
|
token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//pub mod handler;
|
//pub mod handler;
|
||||||
//pub mod routes;
|
//pub mod routes;
|
||||||
|
|
||||||
mod handler;
|
|
||||||
mod extractor;
|
mod extractor;
|
||||||
|
mod handler;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
routing::{get, put,},
|
|
||||||
Router,
|
Router,
|
||||||
|
routing::{get, put},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::rooms::handler::*;
|
use crate::rooms::handler::*;
|
||||||
use crate::utils::db_pool::{
|
use crate::utils::db_pool::{AppState, HotelPool};
|
||||||
HotelPool,
|
|
||||||
AppState,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ROOTS
|
// ROOTS
|
||||||
pub fn rooms_routes() -> Router<AppState> {
|
pub fn rooms_routes() -> Router<AppState> {
|
||||||
|
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/", get(hello_rooms))
|
.route("/", get(hello_rooms))
|
||||||
.route("/clean_db_update/{room_id}", put(clean_db_update))
|
.route("/clean_db_update/{room_id}", put(clean_db_update))
|
||||||
|
|||||||
@@ -1,31 +1,23 @@
|
|||||||
use axum::{
|
use axum::Router;
|
||||||
Router,
|
use r2d2::Pool;
|
||||||
};
|
|
||||||
use r2d2_sqlite::SqliteConnectionManager;
|
use r2d2_sqlite::SqliteConnectionManager;
|
||||||
use r2d2::{Pool};
|
|
||||||
|
|
||||||
use crate::rooms::routes::rooms_routes;
|
|
||||||
use crate::utils::routes::utils_routes;
|
|
||||||
use crate::chat::routes::chat_routes;
|
use crate::chat::routes::chat_routes;
|
||||||
use crate::inventory::routes::inventory_routes;
|
use crate::inventory::routes::inventory_routes;
|
||||||
|
use crate::rooms::routes::rooms_routes;
|
||||||
|
use crate::utils::routes::utils_routes;
|
||||||
|
|
||||||
use crate::utils::db_pool::{AppState};
|
use crate::utils::db_pool::AppState;
|
||||||
//TODO: add secret fomr dotenv here
|
//TODO: add secret fomr dotenv here
|
||||||
/*
|
/*
|
||||||
Function to build our main router
|
Function to build our main router
|
||||||
that regroup all feature centered router
|
that regroup all feature centered router
|
||||||
*/
|
*/
|
||||||
pub fn create_router(state: AppState) -> Router {
|
pub fn create_router(state: AppState) -> Router {
|
||||||
|
|
||||||
Router::new()
|
Router::new()
|
||||||
|
|
||||||
.nest("/auth", utils_routes().with_state(state.clone()))
|
.nest("/auth", utils_routes().with_state(state.clone()))
|
||||||
.nest("/rooms", rooms_routes().with_state(state.clone()))
|
.nest("/rooms", rooms_routes().with_state(state.clone()))
|
||||||
.nest("/chat", chat_routes().with_state(state.clone()))
|
.nest("/chat", chat_routes().with_state(state.clone()))
|
||||||
.nest("/inventory", inventory_routes().with_state(state.clone()))
|
.nest("/inventory", inventory_routes().with_state(state.clone()))
|
||||||
|
|
||||||
.with_state(state)
|
.with_state(state)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,12 @@
|
|||||||
use std::sync::Arc;
|
use axum::extract::{
|
||||||
|
State,
|
||||||
|
ws::{Message, WebSocket, WebSocketUpgrade},
|
||||||
|
};
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use r2d2::{Pool};
|
use r2d2::Pool;
|
||||||
use r2d2_sqlite::SqliteConnectionManager;
|
use r2d2_sqlite::SqliteConnectionManager;
|
||||||
|
use std::sync::Arc;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use axum::extract::{ws::{Message, WebSocket, WebSocketUpgrade}, State};
|
|
||||||
|
|
||||||
use crate::utils::websocket::WsMap;
|
use crate::utils::websocket::WsMap;
|
||||||
|
|
||||||
@@ -14,7 +17,6 @@ use crate::utils::websocket::WsMap;
|
|||||||
pub ws_map: WsMap,
|
pub ws_map: WsMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type HotelId = i32; // or i32 if you want numeric ids
|
type HotelId = i32; // or i32 if you want numeric ids
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
pub mod db_pool;
|
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
|
pub mod db_pool;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
pub mod websocket;
|
pub mod websocket;
|
||||||
@@ -1,33 +1,29 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
routing::{get, put, post},
|
|
||||||
Router,
|
Router,
|
||||||
|
routing::{get, post, put},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils::auth::*;
|
use crate::utils::auth::*;
|
||||||
use crate::utils::db_pool::{HotelPool, AppState, };
|
use crate::utils::db_pool::{AppState, HotelPool};
|
||||||
use crate::utils::websocket::ws_handler;
|
use crate::utils::websocket::ws_handler;
|
||||||
use headers::UserAgent;
|
|
||||||
use axum_extra::TypedHeader;
|
use axum_extra::TypedHeader;
|
||||||
|
use headers::UserAgent;
|
||||||
|
|
||||||
// ROOTS
|
// ROOTS
|
||||||
pub fn utils_routes() -> Router<AppState> {
|
pub fn utils_routes() -> Router<AppState> {
|
||||||
|
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/login", put(clean_auth_loging))
|
.route("/login", put(clean_auth_loging))
|
||||||
.route("/register", put(register_user))
|
.route("/register", put(register_user))
|
||||||
.route("/ws/", get(ws_handler))
|
|
||||||
.route("/tokentest", put(token_tester))
|
.route("/tokentest", put(token_tester))
|
||||||
.route("/force_update_password", put(ForceUpdatePassword))
|
.route("/update_password", put(update_password))
|
||||||
.route("/update_password", put(UpdatePassword))
|
|
||||||
|
|
||||||
.route("/create_refresh", post(create_refresh_token))
|
.route("/create_refresh", post(create_refresh_token))
|
||||||
.route("/login_refresh_token", post(login_refresh_token))
|
.route("/login_refresh_token", post(login_refresh_token))
|
||||||
|
|
||||||
.route("/logout_single_device", post(logout_from_single_device))
|
.route("/logout_single_device", post(logout_from_single_device))
|
||||||
.route("/logout_all_devices", post(logout_from_all_devices))
|
.route("/logout_all_devices", post(logout_from_all_devices))
|
||||||
|
.route("/ws/{req_token}", get(ws_handler))
|
||||||
|
.route("/force_update_password", put(force_update_password))
|
||||||
|
.route("/get_hotels", get(get_hotel))
|
||||||
|
.route("/add_hotel_user", put(add_hotel_user))
|
||||||
|
|
||||||
//.with_state(state)
|
//.with_state(state)
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,23 @@
|
|||||||
use dashmap::DashMap;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use axum::extract::{ws::{Message, WebSocket, WebSocketUpgrade}, State};
|
|
||||||
use tokio::sync::mpsc;
|
|
||||||
use axum::extract::Path;
|
use axum::extract::Path;
|
||||||
use axum::response::IntoResponse;
|
use axum::response::IntoResponse;
|
||||||
|
use axum::{
|
||||||
|
Extension,
|
||||||
|
extract::{
|
||||||
|
State,
|
||||||
|
ws::{Message, WebSocket, WebSocketUpgrade},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use dashmap::DashMap;
|
||||||
|
use reqwest::StatusCode;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::mpsc;
|
||||||
//use futures_util::stream::stream::StreamExt;
|
//use futures_util::stream::stream::StreamExt;
|
||||||
use futures_util::{StreamExt, SinkExt};
|
use futures_util::{SinkExt, StreamExt};
|
||||||
|
|
||||||
use crate::utils::{auth::AuthClaims, db_pool::{AppState, HotelPool}};
|
|
||||||
|
|
||||||
|
|
||||||
|
use crate::utils::{
|
||||||
|
auth::{AuthClaims, JwtKeys, auth_claims_from_token},
|
||||||
|
db_pool::{AppState, HotelPool},
|
||||||
|
};
|
||||||
|
|
||||||
/// Type alias: user_id → sender to that user
|
/// Type alias: user_id → sender to that user
|
||||||
pub type UserMap = DashMap<i32, mpsc::UnboundedSender<Message>>;
|
pub type UserMap = DashMap<i32, mpsc::UnboundedSender<Message>>;
|
||||||
@@ -19,13 +27,7 @@ pub type HotelMap = DashMap<i32, Arc<UserMap>>;
|
|||||||
pub type WsMap = Arc<HotelMap>;
|
pub type WsMap = Arc<HotelMap>;
|
||||||
/// Type alias: user_id → sender to that user
|
/// Type alias: user_id → sender to that user
|
||||||
|
|
||||||
|
async fn handle_socket(mut socket: WebSocket, state: AppState, hotel_id: i32, user_id: i32) {
|
||||||
async fn handle_socket(
|
|
||||||
mut socket: WebSocket,
|
|
||||||
state: AppState,
|
|
||||||
hotel_id: i32,
|
|
||||||
user_id: i32,
|
|
||||||
) {
|
|
||||||
// channel for sending messages TO this client
|
// channel for sending messages TO this client
|
||||||
let (tx, mut rx) = mpsc::unbounded_channel::<Message>();
|
let (tx, mut rx) = mpsc::unbounded_channel::<Message>();
|
||||||
|
|
||||||
@@ -44,8 +46,6 @@ async fn handle_socket(
|
|||||||
// split socket into sender/receiver
|
// split socket into sender/receiver
|
||||||
let (mut sender, mut receiver) = socket.split();
|
let (mut sender, mut receiver) = socket.split();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// task for sending messages from server to client
|
// task for sending messages from server to client
|
||||||
let mut rx_task = tokio::spawn(async move {
|
let mut rx_task = tokio::spawn(async move {
|
||||||
while let Some(msg) = rx.recv().await {
|
while let Some(msg) = rx.recv().await {
|
||||||
@@ -89,12 +89,32 @@ async fn handle_socket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn ws_handler(
|
pub async fn ws_handler(
|
||||||
AuthClaims {user_id, hotel_id}: AuthClaims,
|
//AuthClaims {user_id, hotel_id}: AuthClaims,
|
||||||
ws: WebSocketUpgrade,
|
ws: WebSocketUpgrade,
|
||||||
|
Extension(keys): Extension<JwtKeys>,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
//Path((hotel_id, user_id)): Path<(i32, i32)>,
|
Path((req_token)): Path<(String)>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
ws.on_upgrade(move |socket| handle_socket(socket, state, hotel_id, user_id))
|
let token = req_token;
|
||||||
|
|
||||||
|
let claims = match auth_claims_from_token(&token, &keys) {
|
||||||
|
Err(_) => {
|
||||||
|
print!("error during auth claims processing");
|
||||||
|
return StatusCode::UNAUTHORIZED.into_response();
|
||||||
|
}
|
||||||
|
Ok(c) => c,
|
||||||
|
};
|
||||||
|
|
||||||
|
print!("{token}, web socket tried to connect",);
|
||||||
|
|
||||||
|
/*
|
||||||
|
let claims = match auth_claims_from_token(&token, &keys) {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(_) => return StatusCode::UNAUTHORIZED.into_response(),
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
ws.on_upgrade(move |socket| handle_socket(socket, state, claims.hotel_id, claims.user_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_ws_state(state: &AppState) {
|
fn print_ws_state(state: &AppState) {
|
||||||
|
|||||||
@@ -1,99 +0,0 @@
|
|||||||
cross build --release --target aarch64-unknown-linux-gnu
|
|
||||||
|
|
||||||
docker run -p 8080:8080 \
|
|
||||||
-v ${PWD}/db:/db \
|
|
||||||
-e JWT_SECRET="my-dev-secret" \
|
|
||||||
rust-api:1.0.0
|
|
||||||
|
|
||||||
GOOD
|
|
||||||
|
|
||||||
docker run
|
|
||||||
--hostname=58ff54b2464c
|
|
||||||
--env=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
||||||
--volume=/w/DEV/hotel-api-rs/db:/app/db
|
|
||||||
--network=bridge
|
|
||||||
--workdir=/app
|
|
||||||
-p 8080:8080
|
|
||||||
--restart=no
|
|
||||||
--runtime=runc
|
|
||||||
-d rust-api:1.0.0
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
docker run `
|
|
||||||
--name hotel-api `
|
|
||||||
-e JWT_SECRET=your_jwt_secret_key `
|
|
||||||
-v "/w/DEV/hotel-api-rs/db:/app/db" `
|
|
||||||
-p 8080:8080 `
|
|
||||||
rust-api:1.0.1
|
|
||||||
|
|
||||||
linux distro
|
|
||||||
|
|
||||||
docker run `
|
|
||||||
--name hotel-api `
|
|
||||||
-e JWT_SECRET=your_jwt_secret_key `
|
|
||||||
-v "/var/lib/hotel-api/db:/app/db" `
|
|
||||||
-p 8080:8080 `
|
|
||||||
rust-api:1.0.2
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BAD
|
|
||||||
|
|
||||||
"Mounts": [
|
|
||||||
{
|
|
||||||
"Type": "bind",
|
|
||||||
"Source": "/w/DEV/hotel-api-rs/db",
|
|
||||||
"Destination": "/app/db ",
|
|
||||||
"Mode": "",
|
|
||||||
"RW": true,
|
|
||||||
"Propagation": "rprivate"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
|
|
||||||
"Mounts": [
|
|
||||||
{
|
|
||||||
"Type": "bind",
|
|
||||||
"Source": "/w/DEV/hotel-api-rs/db",
|
|
||||||
"Destination": "/app/db",
|
|
||||||
"Mode": "",
|
|
||||||
"RW": true,
|
|
||||||
"Propagation": "rprivate"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
|
|
||||||
"Mounts": [
|
|
||||||
{
|
|
||||||
"Type": "bind",
|
|
||||||
"Source": "W:\\DEV\\hotel-api-rs\\db\\db.sqlite",
|
|
||||||
"Destination": "/app/db/db.sqlite",
|
|
||||||
"Mode": "",
|
|
||||||
"RW": true,
|
|
||||||
"Propagation": "rprivate"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
GOOD
|
|
||||||
|
|
||||||
"Mounts": [
|
|
||||||
{
|
|
||||||
"Type": "bind",
|
|
||||||
"Source": "/w/DEV/hotel-api-rs/db",
|
|
||||||
"Destination": "/app/db",
|
|
||||||
"Mode": "",
|
|
||||||
"RW": true,
|
|
||||||
"Propagation": "rprivate"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user