Get and store steam username and display it on the homepage
This commit is contained in:
255
Cargo.lock
generated
255
Cargo.lock
generated
@@ -54,6 +54,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic-waker"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "attribute-derive"
|
name = "attribute-derive"
|
||||||
version = "0.9.2"
|
version = "0.9.2"
|
||||||
@@ -157,6 +163,7 @@ dependencies = [
|
|||||||
"diesel-async",
|
"diesel-async",
|
||||||
"diesel_async_migrations",
|
"diesel_async_migrations",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"reqwest 0.12.7",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"steam-openid",
|
"steam-openid",
|
||||||
@@ -850,6 +857,25 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "h2"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205"
|
||||||
|
dependencies = [
|
||||||
|
"atomic-waker",
|
||||||
|
"bytes",
|
||||||
|
"fnv",
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"http 1.1.0",
|
||||||
|
"indexmap",
|
||||||
|
"slab",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "half"
|
name = "half"
|
||||||
version = "2.4.1"
|
version = "2.4.1"
|
||||||
@@ -980,7 +1006,7 @@ dependencies = [
|
|||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2",
|
"h2 0.3.26",
|
||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"http-body 0.4.6",
|
"http-body 0.4.6",
|
||||||
"httparse",
|
"httparse",
|
||||||
@@ -1003,6 +1029,7 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"h2 0.4.6",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"http-body 1.0.1",
|
"http-body 1.0.1",
|
||||||
"httparse",
|
"httparse",
|
||||||
@@ -1011,6 +1038,24 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"want",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-rustls"
|
||||||
|
version = "0.27.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
|
||||||
|
dependencies = [
|
||||||
|
"futures-util",
|
||||||
|
"http 1.1.0",
|
||||||
|
"hyper 1.4.1",
|
||||||
|
"hyper-util",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"tokio",
|
||||||
|
"tokio-rustls",
|
||||||
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1026,6 +1071,22 @@ dependencies = [
|
|||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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 1.4.1",
|
||||||
|
"hyper-util",
|
||||||
|
"native-tls",
|
||||||
|
"tokio",
|
||||||
|
"tokio-native-tls",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-util"
|
name = "hyper-util"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@@ -1033,12 +1094,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
|
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http 1.1.0",
|
||||||
"http-body 1.0.1",
|
"http-body 1.0.1",
|
||||||
"hyper 1.4.1",
|
"hyper 1.4.1",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"socket2",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tower",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1908,11 +1974,11 @@ dependencies = [
|
|||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2",
|
"h2 0.3.26",
|
||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"http-body 0.4.6",
|
"http-body 0.4.6",
|
||||||
"hyper 0.14.30",
|
"hyper 0.14.30",
|
||||||
"hyper-tls",
|
"hyper-tls 0.5.0",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
@@ -1921,12 +1987,12 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile 1.0.4",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"sync_wrapper 0.1.2",
|
"sync_wrapper 0.1.2",
|
||||||
"system-configuration",
|
"system-configuration 0.5.1",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-native-tls",
|
"tokio-native-tls",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
@@ -1937,6 +2003,64 @@ dependencies = [
|
|||||||
"winreg",
|
"winreg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "reqwest"
|
||||||
|
version = "0.12.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"bytes",
|
||||||
|
"encoding_rs",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"h2 0.4.6",
|
||||||
|
"http 1.1.0",
|
||||||
|
"http-body 1.0.1",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper 1.4.1",
|
||||||
|
"hyper-rustls",
|
||||||
|
"hyper-tls 0.6.0",
|
||||||
|
"hyper-util",
|
||||||
|
"ipnet",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"mime",
|
||||||
|
"native-tls",
|
||||||
|
"once_cell",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite",
|
||||||
|
"rustls-pemfile 2.1.3",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"sync_wrapper 1.0.1",
|
||||||
|
"system-configuration 0.6.1",
|
||||||
|
"tokio",
|
||||||
|
"tokio-native-tls",
|
||||||
|
"tower-service",
|
||||||
|
"url",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
"windows-registry",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.17.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"getrandom",
|
||||||
|
"libc",
|
||||||
|
"spin",
|
||||||
|
"untrusted",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rstml"
|
name = "rstml"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
@@ -1976,6 +2100,19 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.23.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"rustls-webpki",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pemfile"
|
name = "rustls-pemfile"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@@ -1985,6 +2122,33 @@ dependencies = [
|
|||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pemfile"
|
||||||
|
version = "2.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"rustls-pki-types",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pki-types"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-webpki"
|
||||||
|
version = "0.102.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.17"
|
version = "1.0.17"
|
||||||
@@ -2308,7 +2472,7 @@ checksum = "b87d7fa6404e4d3227681e436ec9b2255cc91acd93a1b6a7fa00a87484e9c7e0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest 0.11.27",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"url",
|
"url",
|
||||||
@@ -2383,6 +2547,9 @@ name = "sync_wrapper"
|
|||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
|
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "system-configuration"
|
name = "system-configuration"
|
||||||
@@ -2392,7 +2559,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
"system-configuration-sys",
|
"system-configuration-sys 0.5.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "system-configuration"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
"core-foundation",
|
||||||
|
"system-configuration-sys 0.6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2405,6 +2583,16 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.12.0"
|
version = "3.12.0"
|
||||||
@@ -2557,6 +2745,17 @@ dependencies = [
|
|||||||
"whoami",
|
"whoami",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-rustls"
|
||||||
|
version = "0.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
|
||||||
|
dependencies = [
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.12"
|
version = "0.7.12"
|
||||||
@@ -2863,6 +3062,12 @@ version = "0.2.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a"
|
checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.5.2"
|
version = "2.5.2"
|
||||||
@@ -3072,6 +3277,36 @@ 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 = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-registry"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
|
||||||
|
dependencies = [
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
|
||||||
|
dependencies = [
|
||||||
|
"windows-result",
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.48.0"
|
version = "0.48.0"
|
||||||
@@ -3271,3 +3506,9 @@ dependencies = [
|
|||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zeroize"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
||||||
|
|||||||
@@ -21,4 +21,6 @@ diesel-async = { version = "0.5", features = ["postgres"] }
|
|||||||
serde_json = "1.0.128"
|
serde_json = "1.0.128"
|
||||||
diesel_async_migrations = { version = "0.15" }
|
diesel_async_migrations = { version = "0.15" }
|
||||||
|
|
||||||
|
reqwest = { version = "0.12", features = ["json"] }
|
||||||
|
|
||||||
common = { path = "../common/" }
|
common = { path = "../common/" }
|
||||||
|
|||||||
@@ -66,7 +66,22 @@ pub mod demos {
|
|||||||
|
|
||||||
pub mod steam {
|
pub mod steam {
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use std::sync::Arc;
|
use serde::Deserialize;
|
||||||
|
use std::{sync::Arc, collections::HashMap};
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel_async::RunQueryDsl;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct ProfileInfoResponse {
|
||||||
|
players: Vec<ProfileInfo>
|
||||||
|
}
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct ProfileInfo {
|
||||||
|
pub steamid: String,
|
||||||
|
pub personaname: String,
|
||||||
|
#[serde(flatten)]
|
||||||
|
other: HashMap<String, serde_json::Value>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn router(url: &str, callback_path: &str) -> axum::Router {
|
pub fn router(url: &str, callback_path: &str) -> axum::Router {
|
||||||
axum::Router::new()
|
axum::Router::new()
|
||||||
@@ -98,6 +113,28 @@ pub mod steam {
|
|||||||
axum::http::StatusCode::BAD_REQUEST
|
axum::http::StatusCode::BAD_REQUEST
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let steam_client = crate::steam_api::Client::new(std::env::var("STEAM_API_KEY").unwrap());
|
||||||
|
let profile_response_data: ProfileInfoResponse = match steam_client.get("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/", &[("steamids", &format!("{}", id))]).await {
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!("Getting Steam Profile Info: {:?}", e);
|
||||||
|
return Err(axum::http::StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut db_con = crate::db_connection().await;
|
||||||
|
for player in profile_response_data.players {
|
||||||
|
let query = diesel::dsl::insert_into(crate::schema::users::dsl::users).values(crate::models::User {
|
||||||
|
steamid: player.steamid,
|
||||||
|
name: player.personaname.clone(),
|
||||||
|
}).on_conflict(crate::schema::users::dsl::steamid).do_update().set((crate::schema::users::dsl::name.eq(player.personaname)));
|
||||||
|
tracing::debug!("Running Query: {:?}", query);
|
||||||
|
|
||||||
|
if let Err(e) = query.execute(&mut db_con).await {
|
||||||
|
tracing::error!("Inserting/Updating user steam info: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
session
|
session
|
||||||
.modify_data(|data| {
|
.modify_data(|data| {
|
||||||
data.steam_id = Some(id);
|
data.steam_id = Some(id);
|
||||||
@@ -109,23 +146,46 @@ pub mod steam {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod user {
|
pub mod user {
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel_async::RunQueryDsl;
|
||||||
|
|
||||||
pub fn router() -> axum::Router {
|
pub fn router() -> axum::Router {
|
||||||
axum::Router::new()
|
axum::Router::new()
|
||||||
.route("/status", axum::routing::get(status))
|
.route("/status", axum::routing::get(status))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn status(session: crate::UserSession) -> axum::http::StatusCode {
|
async fn status(session: crate::UserSession) -> Result<axum::response::Json<common::UserStatus>, reqwest::StatusCode> {
|
||||||
if session.data().steam_id.is_some() {
|
let steam_id = match session.data().steam_id {
|
||||||
axum::http::StatusCode::OK
|
Some(s) => s,
|
||||||
} else {
|
None => {
|
||||||
axum::http::StatusCode::UNAUTHORIZED
|
return Err(axum::http::StatusCode::UNAUTHORIZED);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
tracing::info!("Load user info");
|
||||||
|
|
||||||
|
let mut db_con = crate::db_connection().await;
|
||||||
|
|
||||||
|
let query = crate::schema::users::dsl::users.filter(crate::schema::users::dsl::steamid.eq(format!("{}", steam_id)));
|
||||||
|
|
||||||
|
let mut result = query.load::<crate::models::User>(&mut db_con).await.unwrap();
|
||||||
|
if result.len() != 1 {
|
||||||
|
tracing::error!("Unexpected query result: {:?}", result);
|
||||||
|
return Err(axum::http::StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
let user_entry = result.pop().unwrap();
|
||||||
|
|
||||||
|
Ok(axum::Json(common::UserStatus {
|
||||||
|
name: user_entry.name,
|
||||||
|
steamid: user_entry.steamid,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn router() -> axum::Router {
|
pub fn router() -> axum::Router {
|
||||||
axum::Router::new()
|
axum::Router::new()
|
||||||
.nest("/steam/", steam::router("http://192.168.0.156:3000", "/api/steam/callback"))
|
.nest("/steam/", steam::router("http://localhost:3000", "/api/steam/callback"))
|
||||||
.nest("/demos/", demos::router("uploads/"))
|
.nest("/demos/", demos::router("uploads/"))
|
||||||
.nest("/user/", user::router())
|
.nest("/user/", user::router())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use diesel_async::RunQueryDsl;
|
use diesel_async::RunQueryDsl;
|
||||||
|
|
||||||
@@ -45,15 +47,19 @@ impl tower_sessions::SessionStore for DieselStore {
|
|||||||
let data = serde_json::to_value(&session_record.data).unwrap();
|
let data = serde_json::to_value(&session_record.data).unwrap();
|
||||||
let expiry_date = self.expiry_to_string(&session_record.expiry_date);
|
let expiry_date = self.expiry_to_string(&session_record.expiry_date);
|
||||||
|
|
||||||
|
let steamid = session_record.data.get(crate::UserSession::KEY).map(|e| serde_json::from_value::<crate::UserSessionData>(e.clone()).ok()).flatten().map(|d| {
|
||||||
|
d.steam_id.map(|s| s.to_string())
|
||||||
|
}).flatten();
|
||||||
|
|
||||||
let query = diesel::dsl::insert_into(crate::schema::sessions::dsl::sessions)
|
let query = diesel::dsl::insert_into(crate::schema::sessions::dsl::sessions)
|
||||||
.values(crate::models::Session {
|
.values(crate::models::Session {
|
||||||
id: db_id,
|
id: db_id,
|
||||||
data: data.clone(),
|
steamid: steamid.clone(),
|
||||||
expiry_date: expiry_date.clone(),
|
expiry_date: expiry_date.clone(),
|
||||||
})
|
})
|
||||||
.on_conflict(crate::schema::sessions::dsl::id)
|
.on_conflict(crate::schema::sessions::dsl::id)
|
||||||
.do_update()
|
.do_update()
|
||||||
.set((crate::schema::sessions::dsl::data.eq(data), crate::schema::sessions::dsl::expiry_date.eq(expiry_date)));
|
.set((crate::schema::sessions::dsl::steamid.eq(steamid), crate::schema::sessions::dsl::expiry_date.eq(expiry_date)));
|
||||||
|
|
||||||
let mut connection = crate::db_connection().await;
|
let mut connection = crate::db_connection().await;
|
||||||
|
|
||||||
@@ -76,11 +82,23 @@ impl tower_sessions::SessionStore for DieselStore {
|
|||||||
return Err(tower_sessions::session_store::Error::Backend("Found more than 1 result".to_string()));
|
return Err(tower_sessions::session_store::Error::Backend("Found more than 1 result".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if result.is_empty() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
let result = result.pop().unwrap();
|
let result = result.pop().unwrap();
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
let mut tmp = HashMap::<String, _>::new();
|
||||||
|
tmp.insert(crate::UserSession::KEY.to_string(), serde_json::to_value(&crate::UserSessionData {
|
||||||
|
steam_id: result.steamid.map(|s| s.parse().ok()).flatten(),
|
||||||
|
}).unwrap());
|
||||||
|
tmp
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Some(tower_sessions::session::Record {
|
Ok(Some(tower_sessions::session::Record {
|
||||||
id: tower_sessions::session::Id(self.bytes_to_id(result.id)),
|
id: tower_sessions::session::Id(self.bytes_to_id(result.id)),
|
||||||
data: serde_json::from_value(result.data).unwrap(),
|
data: data,
|
||||||
expiry_date: self.string_to_expiry(&result.expiry_date),
|
expiry_date: self.string_to_expiry(&result.expiry_date),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,3 +34,35 @@ pub async fn get_demo_from_upload(name: &str, mut form: axum::extract::Multipart
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod api;
|
pub mod api;
|
||||||
|
pub mod steam_api {
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
pub struct Client {
|
||||||
|
http: reqwest::Client,
|
||||||
|
api_key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Response<T> {
|
||||||
|
response: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
pub fn new<IS>(api_key: IS) -> Self where IS: Into<String> {
|
||||||
|
Self {
|
||||||
|
http: reqwest::Client::new(),
|
||||||
|
api_key: api_key.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get<T>(&self, path: &str, args: &[(&str, &str)]) -> Result<T, ()> where T: serde::de::DeserializeOwned {
|
||||||
|
let response = self.http.get(path).query(&[("key", &self.api_key)]).query(args).send().await.map_err(|e| ())?;
|
||||||
|
if !response.status().is_success() {
|
||||||
|
dbg!(&response);
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
response.json::<Response<T>>().await.map(|r| r.response).map_err(|e| ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use diesel::prelude::*;
|
|||||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
pub id: Vec<i64>,
|
pub id: Vec<i64>,
|
||||||
pub data: serde_json::Value,
|
pub steamid: Option<String>,
|
||||||
pub expiry_date: String,
|
pub expiry_date: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,3 +16,11 @@ pub struct Demo {
|
|||||||
pub steam_id: i64,
|
pub steam_id: i64,
|
||||||
pub demo_id: i64,
|
pub demo_id: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Queryable, Selectable, Insertable, Debug)]
|
||||||
|
#[diesel(table_name = crate::schema::users)]
|
||||||
|
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||||
|
pub struct User {
|
||||||
|
pub steamid: String,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
diesel::table! {
|
diesel::table! {
|
||||||
sessions (id) {
|
sessions (id) {
|
||||||
id -> Array<BigInt>,
|
id -> Array<BigInt>,
|
||||||
data -> Jsonb,
|
steamid -> Nullable<Text>,
|
||||||
expiry_date -> Text,
|
expiry_date -> Text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
demos (steam_id) {
|
demos (steam_id, demo_id) {
|
||||||
steam_id -> BigInt,
|
steam_id -> BigInt,
|
||||||
demo_id -> BigInt
|
demo_id -> BigInt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
users (steamid) {
|
||||||
|
steamid -> Text,
|
||||||
|
name -> Text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub struct UserSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UserSession {
|
impl UserSession {
|
||||||
const KEY: &'static str = "user.data";
|
pub const KEY: &'static str = "user.data";
|
||||||
|
|
||||||
pub fn data(&self) -> &UserSessionData {
|
pub fn data(&self) -> &UserSessionData {
|
||||||
&self.data
|
&self.data
|
||||||
|
|||||||
@@ -2,3 +2,9 @@
|
|||||||
pub struct BaseDemoInfo {
|
pub struct BaseDemoInfo {
|
||||||
pub id: i64,
|
pub id: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct UserStatus {
|
||||||
|
pub name: String,
|
||||||
|
pub steamid: String,
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,15 @@ use leptos_router::A;
|
|||||||
mod demo;
|
mod demo;
|
||||||
pub use demo::Demo;
|
pub use demo::Demo;
|
||||||
|
|
||||||
|
mod navbar;
|
||||||
|
pub use navbar::TopBar;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum DemoUploadStatus {
|
||||||
|
Hidden,
|
||||||
|
Shown,
|
||||||
|
}
|
||||||
|
|
||||||
#[leptos::component]
|
#[leptos::component]
|
||||||
pub fn demo_list_entry(demo: common::BaseDemoInfo) -> impl leptos::IntoView {
|
pub fn demo_list_entry(demo: common::BaseDemoInfo) -> impl leptos::IntoView {
|
||||||
view! {
|
view! {
|
||||||
@@ -14,92 +23,44 @@ pub fn demo_list_entry(demo: common::BaseDemoInfo) -> impl leptos::IntoView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[leptos::component]
|
#[leptos::component]
|
||||||
pub fn steam_login(height: &'static str, width: &'static str) -> impl leptos::IntoView {
|
pub fn upload_demo(shown: ReadSignal<DemoUploadStatus>, update_shown: WriteSignal<DemoUploadStatus>) -> impl leptos::IntoView {
|
||||||
let user_status = create_resource(|| (), |_| async move {
|
|
||||||
let res = reqwasm::http::Request::get("/api/user/status").send().await.unwrap();
|
|
||||||
res.status() == 200
|
|
||||||
});
|
|
||||||
|
|
||||||
let tmp = move || if user_status.get().unwrap_or(false) {
|
|
||||||
view! {
|
|
||||||
<p>Logged in</p>
|
|
||||||
}.into_any()
|
|
||||||
} else {
|
|
||||||
view! {
|
|
||||||
<a href="/api/steam/login">
|
|
||||||
<img src="https://community.akamai.steamstatic.com/public/images/signinthroughsteam/sits_01.png" alt="Steam Login" style=format!("height: {height}; width: {width}") />
|
|
||||||
</a>
|
|
||||||
}.into_any()
|
|
||||||
};
|
|
||||||
|
|
||||||
view! {
|
|
||||||
{ tmp }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[leptos::component]
|
|
||||||
pub fn upload_demo() -> impl leptos::IntoView {
|
|
||||||
use leptos_router::Form;
|
use leptos_router::Form;
|
||||||
|
|
||||||
view! {
|
let style = stylers::style! {
|
||||||
<div>
|
"UploadDemo",
|
||||||
|
.container {
|
||||||
|
position: absolute;
|
||||||
|
left: 25vw;
|
||||||
|
top: 15vh;
|
||||||
|
width: 48vw;
|
||||||
|
height: 18vh;
|
||||||
|
padding: 1vh 1vw;
|
||||||
|
|
||||||
|
color: #f1f1f1;
|
||||||
|
background-color: #42424d;
|
||||||
|
|
||||||
|
border-radius: 10px;
|
||||||
|
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container.shown {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
view! {class = style,
|
||||||
|
<div class="container" class:shown=move || shown() == DemoUploadStatus::Shown>
|
||||||
|
<h3>Upload a Demo</h3>
|
||||||
|
|
||||||
<Form action="/api/demos/upload" method="post" enctype="multipart/form-data".to_string()>
|
<Form action="/api/demos/upload" method="post" enctype="multipart/form-data".to_string()>
|
||||||
<p> Select File to upload </p>
|
<p> Select File to upload </p>
|
||||||
<input type="file" name="demo" id="demo"></input>
|
<input type="file" name="demo" id="demo"></input>
|
||||||
<input type="submit" value="Upload Image" name="submit"></input>
|
<input type="submit" value="Upload Image" name="submit"></input>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
<button on:click=move |_| update_shown(DemoUploadStatus::Hidden)>
|
||||||
}
|
Close
|
||||||
}
|
</button>
|
||||||
|
|
||||||
#[leptos::component]
|
|
||||||
pub fn top_bar() -> impl leptos::IntoView {
|
|
||||||
let style = stylers::style! {
|
|
||||||
"TopBar",
|
|
||||||
.bar {
|
|
||||||
width: 100%;
|
|
||||||
height: 4vh;
|
|
||||||
padding-top: 0.5vh;
|
|
||||||
padding-bottom: 0.5vh;
|
|
||||||
|
|
||||||
background-color: #28282f;
|
|
||||||
color: #d5d5d5;
|
|
||||||
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 15vw auto auto calc(4vh * (180/35) + 20px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.group {
|
|
||||||
display: block;
|
|
||||||
width: 30vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.elem {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
color: #d5d5d5;
|
|
||||||
width: 15vw;
|
|
||||||
font-size: 24px;
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
view! {class = style,
|
|
||||||
<div class="bar">
|
|
||||||
<A href="/">
|
|
||||||
<p class="logo">Knifer</p>
|
|
||||||
</A>
|
|
||||||
|
|
||||||
<div class="elem">
|
|
||||||
Upload Demo
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="elem" style="grid-column-start: 4">
|
|
||||||
<SteamLogin height="4vh" width="auto" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,7 +77,6 @@ pub fn homepage() -> impl leptos::IntoView {
|
|||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Demos</h2>
|
<h2>Demos</h2>
|
||||||
<UploadDemo />
|
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
{ move || demo_data.get().unwrap_or_default().into_iter().map(|demo| crate::DemoListEntry(DemoListEntryProps {
|
{ move || demo_data.get().unwrap_or_default().into_iter().map(|demo| crate::DemoListEntry(DemoListEntryProps {
|
||||||
|
|||||||
@@ -15,12 +15,16 @@ fn main() {
|
|||||||
load_demos().await
|
load_demos().await
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let (upload_demo_read, upload_demo_write) = create_signal(frontend::DemoUploadStatus::Hidden);
|
||||||
|
|
||||||
mount_to_body(move || view! {
|
mount_to_body(move || view! {
|
||||||
<Router>
|
<Router>
|
||||||
<nav>
|
<nav>
|
||||||
<TopBar />
|
<TopBar update_demo_visible=upload_demo_write />
|
||||||
</nav>
|
</nav>
|
||||||
<main>
|
<main>
|
||||||
|
<UploadDemo shown=upload_demo_read update_shown=upload_demo_write />
|
||||||
|
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" view=Homepage />
|
<Route path="/" view=Homepage />
|
||||||
<Route path="/demo/:id" view=Demo />
|
<Route path="/demo/:id" view=Demo />
|
||||||
|
|||||||
80
frontend/src/navbar.rs
Normal file
80
frontend/src/navbar.rs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
use leptos::*;
|
||||||
|
use leptos_router::A;
|
||||||
|
|
||||||
|
use crate::DemoUploadStatus;
|
||||||
|
|
||||||
|
#[leptos::component]
|
||||||
|
fn steam_login(height: &'static str, width: &'static str) -> impl leptos::IntoView {
|
||||||
|
let user_status = create_resource(|| (), |_| async move {
|
||||||
|
let res = reqwasm::http::Request::get("/api/user/status").send().await.unwrap();
|
||||||
|
res.json::<common::UserStatus>().await.map_err(|e| ())
|
||||||
|
});
|
||||||
|
|
||||||
|
let tmp = move || match user_status.get() {
|
||||||
|
Some(Ok(user)) =>
|
||||||
|
view! {
|
||||||
|
<p>{user.name}</p>
|
||||||
|
}.into_view(),
|
||||||
|
_ =>
|
||||||
|
view! {
|
||||||
|
<a href="/api/steam/login" rel="external">
|
||||||
|
<img src="https://community.akamai.steamstatic.com/public/images/signinthroughsteam/sits_01.png" alt="Steam Login" style=format!("height: {height}; width: {width}") />
|
||||||
|
</a>
|
||||||
|
}.into_view(),
|
||||||
|
};
|
||||||
|
|
||||||
|
view! {
|
||||||
|
{ tmp }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[leptos::component]
|
||||||
|
pub fn top_bar(update_demo_visible: WriteSignal<DemoUploadStatus>) -> impl leptos::IntoView {
|
||||||
|
let style = stylers::style! {
|
||||||
|
"TopBar",
|
||||||
|
.bar {
|
||||||
|
width: 100%;
|
||||||
|
height: 4vh;
|
||||||
|
padding-top: 0.5vh;
|
||||||
|
padding-bottom: 0.5vh;
|
||||||
|
|
||||||
|
background-color: #28282f;
|
||||||
|
color: #d5d5d5;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 15vw auto 10vw calc(4vh * (180/35) + 20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.elem {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
color: #d5d5d5;
|
||||||
|
width: 15vw;
|
||||||
|
font-size: 24px;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
view! {class = style,
|
||||||
|
<div class="bar">
|
||||||
|
<A href="/">
|
||||||
|
<p class="logo">Knifer</p>
|
||||||
|
</A>
|
||||||
|
|
||||||
|
<div class="elem" style="grid-column-start: 3">
|
||||||
|
<button on:click=move |_| update_demo_visible(DemoUploadStatus::Shown)>
|
||||||
|
Upload Demo
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elem" style="grid-column-start: 4">
|
||||||
|
<SteamLogin height="4vh" width="auto" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
-- Your SQL goes here
|
-- Your SQL goes here
|
||||||
CREATE TABLE IF NOT EXISTS sessions (
|
CREATE TABLE IF NOT EXISTS sessions (
|
||||||
id bigint[2] PRIMARY KEY,
|
id bigint[2] PRIMARY KEY,
|
||||||
data jsonb,
|
steamid TEXT,
|
||||||
expiry_date TEXT
|
expiry_date TEXT
|
||||||
)
|
)
|
||||||
|
|||||||
2
migrations/2024-09-10-123500_users/down.sql
Normal file
2
migrations/2024-09-10-123500_users/down.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
DROP TABLE users
|
||||||
5
migrations/2024-09-10-123500_users/up.sql
Normal file
5
migrations/2024-09-10-123500_users/up.sql
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
-- Your SQL goes here
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
steamid TEXT PRIMARY KEY,
|
||||||
|
name TEXT
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user