Merge branch '21-upgrade-to-leptos-0-6' into 24-switch-from-actix-to-axum

This commit is contained in:
Ethan Girouard 2024-03-31 01:14:23 -04:00
commit c4c88a2905
Signed by: eta357
GPG Key ID: 7BCDC36DFD11C146
20 changed files with 834 additions and 149 deletions

17
.env.example Normal file
View File

@ -0,0 +1,17 @@
# Example environment variable file
# Copy this to .env or manually set the environment variables
# Redis URL -- Used for storing session data
REDIS_URL=redis://localhost:6379
# PostgreSQL URL -- Used for storing data
# Option 1: Specify the URL directly
DATABASE_URL=postgresql://libretunes:password@localhost:5432/libretunes
# Option 2: Specify the individual components
# Must specify at least POSTGRES_HOST
# POSTGRES_USER=libretunes
# POSTGRES_PASSWORD=password
# POSTGRES_HOST=localhost
# POSTGRES_PORT=5432
# POSTGRES_DB=libretunes

View File

@ -2,17 +2,25 @@
build: build:
needs: [] needs: []
image: $CI_REGISTRY/libretunes/ops/docker-leptos:latest image: $CI_REGISTRY/libretunes/ops/docker-leptos:latest
variables:
RUSTFLAGS: "-D warnings"
script: script:
- cargo-leptos build - cargo-leptos build
.docker:
image: docker:latest
services:
- docker:dind
tags:
- docker
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
# Build the docker image and push it to the registry # Build the docker image and push it to the registry
docker-build: docker-build:
needs: ["build"] needs: ["build"]
image: docker:latest extends: .docker
script: script:
- /usr/local/bin/dockerd-entrypoint.sh &
- while ! docker info; do echo "Waiting for Docker to become available..."; sleep 1; done
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA . - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
# If running on the default branch, tag as latest # If running on the default branch, tag as latest
- if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then docker tag - if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then docker tag
@ -44,35 +52,50 @@ cargo-doc:
paths: paths:
- target/doc - target/doc
.argocd:
image: argoproj/argocd:v2.6.15
before_script:
- argocd login ${ARGOCD_SERVER} --username ${ARGOCD_USERNAME} --password ${ARGOCD_PASSWORD} --grpc-web
# Start the review environment # Start the review environment
start-review: start-review:
extends: .argocd extends: .docker
rules: rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual when: manual
script: script:
- argocd app sync argocd/libretunes-review-${CI_COMMIT_SHORT_SHA} - apk add curl openssl
- argocd app wait argocd/libretunes-review-${CI_COMMIT_SHORT_SHA} - cd cicd
- echo "$CLOUDFLARE_TUNNEL_AUTH_JSON" > tunnel-auth.json
- ./add-dns.sh $CLOUDFLARE_ZONE_ID review-$CI_COMMIT_SHORT_SHA libretunes-auto-review $CLOUDFLARE_API_TOKEN $CLOUDFLARE_TUNNEL_ID
- ./create-tunnel-config.sh http://libretunes:3000 review-$CI_COMMIT_SHORT_SHA.libretunes.xyz $CLOUDFLARE_TUNNEL_ID
- export COMPOSE_PROJECT_NAME=review-$CI_COMMIT_SHORT_SHA
- export POSTGRES_PASSWORD=$(openssl rand -hex 16)
- export LIBRETUNES_VERSION=$CI_COMMIT_SHORT_SHA
- docker compose --file docker-compose-cicd.yml pull
- docker compose --file docker-compose-cicd.yml create
- export CONFIG_VOL_NAME=review-${CI_COMMIT_SHORT_SHA}_cloudflared-config
- export TMP_CONTAINER_NAME=$(docker run --rm -d -v $CONFIG_VOL_NAME:/data busybox sh -c "sleep infinity")
- docker cp tunnel-auth.json $TMP_CONTAINER_NAME:/data/auth.json
- docker cp cloudflared-tunnel-config.yml $TMP_CONTAINER_NAME:/data/config.yml
- docker stop $TMP_CONTAINER_NAME
- docker compose --file docker-compose-cicd.yml up -d
environment: environment:
name: review/$CI_COMMIT_SHORT_SHA name: review/$CI_COMMIT_SHORT_SHA
url: https://review-$CI_COMMIT_SHORT_SHA.libretunes.mregirouard.com url: https://review-$CI_COMMIT_SHORT_SHA.libretunes.xyz
on_stop: stop-review on_stop: stop-review
auto_stop_in: 1 week
# Stop the review environment # Stop the review environment
stop-review: stop-review:
needs: ["start-review"] needs: ["start-review"]
extends: .argocd extends: .docker
rules: rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual when: manual
allow_failure: true allow_failure: true
script: script:
- argocd app delete argocd/libretunes-review-${CI_COMMIT_SHORT_SHA} --cascade - apk add jq curl
- ./cicd/remove-dns.sh $CLOUDFLARE_ZONE_ID review-$CI_COMMIT_SHORT_SHA.libretunes.xyz libretunes-auto-review $CLOUDFLARE_API_TOKEN
- export COMPOSE_PROJECT_NAME=review-$CI_COMMIT_SHORT_SHA
- export LIBRETUNES_VERSION=$CI_COMMIT_SHORT_SHA
- docker compose --file cicd/docker-compose-cicd.yml down
- docker compose --file cicd/docker-compose-cicd.yml rm -f -v
environment: environment:
name: review/$CI_COMMIT_SHORT_SHA name: review/$CI_COMMIT_SHORT_SHA
action: stop action: stop

657
Cargo.lock generated
View File

@ -760,6 +760,19 @@ dependencies = [
"toml 0.5.11", "toml 0.5.11",
] ]
[[package]]
name = "config"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7328b20597b53c2454f0b1919720c25c7339051c02b72b7e05409e00b14132be"
dependencies = [
"lazy_static",
"nom",
"pathdiff",
"serde",
"toml 0.8.12",
]
[[package]] [[package]]
name = "console_error_panic_hook" name = "console_error_panic_hook"
version = "0.1.7" version = "0.1.7"
@ -923,6 +936,19 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "dashmap"
version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
dependencies = [
"cfg-if",
"hashbrown 0.14.3",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]] [[package]]
name = "deranged" name = "deranged"
version = "0.3.10" version = "0.3.10"
@ -1231,7 +1257,28 @@ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-sink", "futures-sink",
"gloo-utils", "gloo-utils 0.1.7",
"js-sys",
"pin-project",
"serde",
"serde_json",
"thiserror",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "gloo-net"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173"
dependencies = [
"futures-channel",
"futures-core",
"futures-sink",
"gloo-utils 0.2.0",
"http 0.2.11",
"js-sys", "js-sys",
"pin-project", "pin-project",
"serde", "serde",
@ -1255,6 +1302,19 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "gloo-utils"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa"
dependencies = [
"js-sys",
"serde",
"serde_json",
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.22" version = "0.3.22"
@ -1450,65 +1510,195 @@ dependencies = [
[[package]] [[package]]
name = "icondata" name = "icondata"
version = "0.0.8" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f41f2deec9249d16ef6b1a8442fbe16013f67053797052aa0b7d2f5ebd0f0098" checksum = "e38f18389f3cd0e664bd42f1dfe0aba4acda0a44036fb720eb07e8ba3a09640c"
dependencies = [ dependencies = [
"icondata_ai", "icondata_ai",
"icondata_bi",
"icondata_bs", "icondata_bs",
"icondata_cg", "icondata_cg",
"icondata_ch",
"icondata_core", "icondata_core",
"icondata_fa",
"icondata_fi",
"icondata_hi",
"icondata_im",
"icondata_io", "icondata_io",
"icondata_lu",
"icondata_oc",
"icondata_ri", "icondata_ri",
"icondata_si",
"icondata_tb",
"icondata_ti",
"icondata_vs",
"icondata_wi",
] ]
[[package]] [[package]]
name = "icondata_ai" name = "icondata_ai"
version = "0.0.8" version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8fe5fa2eed7715d5388e046d97f09d3baddd155b487454eb9cda3168c79d4b" checksum = "9bf3a9c196a6a169f790639ecc8fdd4396660b1d53b905230bf0b364776a56fc"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_bi"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6ce125f0d203e66444b02982af9b15631f2385573ad7992af79d4d4babc638d"
dependencies = [ dependencies = [
"icondata_core", "icondata_core",
] ]
[[package]] [[package]]
name = "icondata_bs" name = "icondata_bs"
version = "0.0.8" version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a1eeaedae6788b08308e1b050eeddaffa62dd5f2368469ef980c8e0e75837e3" checksum = "67940e592b0b8df8d7adc055c8542d135ce1d7d6ad01d8fb8de9405ebfc21c2e"
dependencies = [ dependencies = [
"icondata_core", "icondata_core",
] ]
[[package]] [[package]]
name = "icondata_cg" name = "icondata_cg"
version = "0.0.8" version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b90cda35aa524761219a8dbd006513734e08a4cf92ee05820b01749e76435462" checksum = "a0eba691ca17a43ffc8ebbcf200cd3ea54ad75837f210a6a6ace87a491be8314"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_ch"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2870b3c4ebf013b7e27af71d4c55f10b97ea448831e9a156cb53fec0f262dc20"
dependencies = [ dependencies = [
"icondata_core", "icondata_core",
] ]
[[package]] [[package]]
name = "icondata_core" name = "icondata_core"
version = "0.0.2" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1640a4c1d5ddd08ab1d9854ffa7a2fa3dc52339492676b6d3031e77ca579f434" checksum = "6c97be924215abd5e630d84e95a47c710138a6559b4c55039f4f33aa897fa859"
[[package]]
name = "icondata_fa"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c7fee576096efe5567a7216a6fb8154db8eae9ae108e5a4706805204208c2af"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_fi"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1a4e81557c205a12ac051046595bb616f388537468987f7ee8960f897cdc538"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_hi"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3435d50de04c61799613995e753e613dc4f2771aa08eb94a7318289a5ea9d784"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_im"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce4bd1d64bb67bb080f605e3e600271894b67c4aaa18965179586ef5990a2297"
dependencies = [
"icondata_core",
]
[[package]] [[package]]
name = "icondata_io" name = "icondata_io"
version = "0.0.8" version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134d9fb91cdd0e7ac971199e2c8c8eb917a975faeeee54b227a0068c4f70c886" checksum = "35b9d681c936a6e087940beb4766159cddc080d7f1fd5ef0ef3ab9f50a11f3f6"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_lu"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d552c45cc3ab1d1bf88cc0201004eb92418141e5454e9e0e46c4b4a4faf66248"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_oc"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8be19499912a05d5db89ccb88dbe3c459ca4100bda3dbcbddff69f2dcf71d305"
dependencies = [ dependencies = [
"icondata_core", "icondata_core",
] ]
[[package]] [[package]]
name = "icondata_ri" name = "icondata_ri"
version = "0.0.8" version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1d3adc5b64b22d10ab23a7b1a005f4cb52f3d08909f578fbaa09af9f9c0b7b" checksum = "114a85cc95d1bfaee8dc5bf8a07dd043fc9e75499dc2ff4ac5e066193c594930"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_si"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc30cb2dbc2ac53f23dddbcb0ad73720970b24c0ed13935df8082b74fb627860"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_tb"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f2b8d8e2047546285805795e6d3cb6e820a52bb008e15942e11353c7ba659f2"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_ti"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f85074d4bf10960d0f2b01ce3d9cfa2b2434a170d0738336411bb61e83227e4"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_vs"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82bb4a8b1523200fc7c3b588bb80858db16708067093110ee8614db63b8913"
dependencies = [
"icondata_core",
]
[[package]]
name = "icondata_wi"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d2c65b534aa9d7ccb107d892200e8fef2d1849acad160af067e9e20ced3619b"
dependencies = [ dependencies = [
"icondata_core", "icondata_core",
] ]
@ -1593,6 +1783,15 @@ dependencies = [
"either", "either",
] ]
[[package]]
name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [
"either",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.10" version = "1.0.10"
@ -1636,12 +1835,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d02b78d6e38acf8199426058a0d8c4030835d84a4ee16147df25be7fed707e0" checksum = "9d02b78d6e38acf8199426058a0d8c4030835d84a4ee16147df25be7fed707e0"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"leptos_config", "leptos_config 0.5.4",
"leptos_dom", "leptos_dom 0.5.4",
"leptos_macro", "leptos_macro 0.5.4",
"leptos_reactive", "leptos_reactive 0.5.4",
"leptos_server", "leptos_server 0.5.4",
"server_fn", "server_fn 0.5.4",
"tracing",
"typed-builder",
"typed-builder-macro",
"web-sys",
]
[[package]]
name = "leptos"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56d079555ff18158a1ed28d2a8ac529b4cb5904490384064346eb2d321addde6"
dependencies = [
"cfg-if",
"leptos_config 0.6.9",
"leptos_dom 0.6.9",
"leptos_macro 0.6.9",
"leptos_reactive 0.6.9",
"leptos_server 0.6.9",
"server_fn 0.6.9",
"tracing", "tracing",
"typed-builder", "typed-builder",
"typed-builder-macro", "typed-builder-macro",
@ -1651,20 +1869,22 @@ dependencies = [
[[package]] [[package]]
name = "leptos_actix" name = "leptos_actix"
version = "0.5.4" version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b2b118a031de24b39be9ef2dcfa03e7e255e98d06a8aa2c53f220155424cf1" checksum = "9edb4789a15864a26d695038f42dcdf1d1c32d3a1f537751ce177c97f4f5e3dd"
dependencies = [ dependencies = [
"actix-http", "actix-http",
"actix-web", "actix-web",
"futures", "futures",
"leptos", "leptos 0.6.9",
"leptos_integration_utils", "leptos_integration_utils 0.6.9",
"leptos_meta", "leptos_macro 0.6.9",
"leptos_router", "leptos_meta 0.6.9",
"leptos_router 0.6.9",
"parking_lot", "parking_lot",
"regex", "regex",
"serde_json", "serde_json",
"server_fn 0.6.9",
"tokio", "tokio",
"tracing", "tracing",
] ]
@ -1680,10 +1900,10 @@ dependencies = [
"futures", "futures",
"http 0.2.11", "http 0.2.11",
"hyper", "hyper",
"leptos", "leptos 0.5.4",
"leptos_integration_utils", "leptos_integration_utils 0.5.4",
"leptos_meta", "leptos_meta 0.5.4",
"leptos_router", "leptos_router 0.5.4",
"once_cell", "once_cell",
"parking_lot", "parking_lot",
"serde_json", "serde_json",
@ -1698,7 +1918,20 @@ version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afcaa5db5b22b794b624e14ffe2aefae215b2d21c60a230ae2d06fe21ae5da64" checksum = "afcaa5db5b22b794b624e14ffe2aefae215b2d21c60a230ae2d06fe21ae5da64"
dependencies = [ dependencies = [
"config", "config 0.13.4",
"regex",
"serde",
"thiserror",
"typed-builder",
]
[[package]]
name = "leptos_config"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d80b4ed5f0447996b9a28879002f995d3770687630f568be41307f362f84cb7"
dependencies = [
"config 0.14.0",
"regex", "regex",
"serde", "serde",
"thiserror", "thiserror",
@ -1720,14 +1953,44 @@ dependencies = [
"indexmap", "indexmap",
"itertools 0.10.5", "itertools 0.10.5",
"js-sys", "js-sys",
"leptos_reactive", "leptos_reactive 0.5.4",
"once_cell", "once_cell",
"pad-adapter", "pad-adapter",
"paste", "paste",
"rustc-hash", "rustc-hash",
"serde", "serde",
"serde_json", "serde_json",
"server_fn", "server_fn 0.5.4",
"smallvec",
"tracing",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "leptos_dom"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a4b4da3cb6a4dde22e68717482a4b926fb5dd182c12461b27efa37764b29d9a"
dependencies = [
"async-recursion",
"cfg-if",
"drain_filter_polyfill",
"futures",
"getrandom",
"html-escape",
"indexmap",
"itertools 0.12.1",
"js-sys",
"leptos_reactive 0.6.9",
"once_cell",
"pad-adapter",
"paste",
"rustc-hash",
"serde",
"serde_json",
"server_fn 0.6.9",
"smallvec", "smallvec",
"tracing", "tracing",
"wasm-bindgen", "wasm-bindgen",
@ -1754,14 +2017,36 @@ dependencies = [
] ]
[[package]] [[package]]
name = "leptos_icons" name = "leptos_hot_reload"
version = "0.1.0" version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b3fad7820b18b983d49ff4262df88de94dc8fd993278937979cc0dd188868e5" checksum = "fb051c7b3bce8368ee30fb57e7b14cdcd573019ea6cd1858b9c697a3519ea099"
dependencies = [ dependencies = [
"icondata", "anyhow",
"leptos", "camino",
"tracing", "indexmap",
"parking_lot",
"proc-macro2",
"quote",
"rstml",
"serde",
"syn 2.0.48",
"walkdir",
]
[[package]]
name = "leptos_icons"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "584bccafed73138f4d700f936e6a82268efec2df9a2f9d74e1ee80985653413e"
dependencies = [
"bytes",
"encoding_rs",
"icondata_core",
"lazy_static",
"leptos 0.6.9",
"log",
"paste",
] ]
[[package]] [[package]]
@ -1771,10 +2056,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dbbd7d721bcdd9aa7b20987063de41314c836a3ac67e263ca489857e337dec" checksum = "c2dbbd7d721bcdd9aa7b20987063de41314c836a3ac67e263ca489857e337dec"
dependencies = [ dependencies = [
"futures", "futures",
"leptos", "leptos 0.5.4",
"leptos_config", "leptos_config 0.5.4",
"leptos_hot_reload", "leptos_hot_reload 0.5.4",
"leptos_meta", "leptos_meta 0.5.4",
"tracing",
]
[[package]]
name = "leptos_integration_utils"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff00799857159434d31b6bd1898e21c63f69f39289621da5a554fcab1c3e7300"
dependencies = [
"futures",
"leptos 0.6.9",
"leptos_config 0.6.9",
"leptos_hot_reload 0.6.9",
"leptos_meta 0.6.9",
"tracing", "tracing",
] ]
@ -1789,13 +2088,36 @@ dependencies = [
"convert_case 0.6.0", "convert_case 0.6.0",
"html-escape", "html-escape",
"itertools 0.11.0", "itertools 0.11.0",
"leptos_hot_reload", "leptos_hot_reload 0.5.4",
"prettyplease", "prettyplease",
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"rstml", "rstml",
"server_fn_macro", "server_fn_macro 0.5.4",
"syn 2.0.48",
"tracing",
"uuid",
]
[[package]]
name = "leptos_macro"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e82c33c8baa07a36c1f0d6149af821be885e6863779bcb24954bf865ad8402b4"
dependencies = [
"attribute-derive",
"cfg-if",
"convert_case 0.6.0",
"html-escape",
"itertools 0.12.1",
"leptos_hot_reload 0.6.9",
"prettyplease",
"proc-macro-error",
"proc-macro2",
"quote",
"rstml",
"server_fn_macro 0.6.9",
"syn 2.0.48", "syn 2.0.48",
"tracing", "tracing",
"uuid", "uuid",
@ -1809,7 +2131,21 @@ checksum = "983bbf829598d275b01e96bd9fca71e4739dd7b9fdf69cb8898b30ebfb124332"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"indexmap", "indexmap",
"leptos", "leptos 0.5.4",
"tracing",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "leptos_meta"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12b9dac59a2f88f5235dbe17cfa81b738a6f47238a64e4f23b921f1a90a9bf11"
dependencies = [
"cfg-if",
"indexmap",
"leptos 0.6.9",
"tracing", "tracing",
"wasm-bindgen", "wasm-bindgen",
"web-sys", "web-sys",
@ -1820,6 +2156,30 @@ name = "leptos_reactive"
version = "0.5.4" version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22207568e096ac153ba8da68635e3136c1ec614ea9012736fa861c05bfb2eeff" checksum = "22207568e096ac153ba8da68635e3136c1ec614ea9012736fa861c05bfb2eeff"
dependencies = [
"base64 0.21.7",
"cfg-if",
"futures",
"indexmap",
"paste",
"pin-project",
"rustc-hash",
"self_cell",
"serde",
"serde-wasm-bindgen 0.5.0",
"serde_json",
"slotmap",
"thiserror",
"tokio",
"tracing",
"wasm-bindgen-futures",
]
[[package]]
name = "leptos_reactive"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93bdcebc9822cc22a72cc9528dd794e1396152c75749ee09959f8272a8c99657"
dependencies = [ dependencies = [
"base64 0.21.7", "base64 0.21.7",
"cfg-if", "cfg-if",
@ -1832,7 +2192,7 @@ dependencies = [
"rustc-hash", "rustc-hash",
"self_cell", "self_cell",
"serde", "serde",
"serde-wasm-bindgen", "serde-wasm-bindgen 0.6.5",
"serde_json", "serde_json",
"slotmap", "slotmap",
"thiserror", "thiserror",
@ -1851,13 +2211,13 @@ checksum = "c1a2ff8b8e8ae8b17efd8be2a407f7f83ed57c5243f70f2d03e6635f9ff61848"
dependencies = [ dependencies = [
"cached", "cached",
"cfg-if", "cfg-if",
"gloo-net", "gloo-net 0.2.6",
"itertools 0.11.0", "itertools 0.11.0",
"js-sys", "js-sys",
"lazy_static", "lazy_static",
"leptos", "leptos 0.5.4",
"leptos_integration_utils", "leptos_integration_utils 0.5.4",
"leptos_meta", "leptos_meta 0.5.4",
"linear-map", "linear-map",
"lru", "lru",
"once_cell", "once_cell",
@ -1874,6 +2234,38 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "leptos_router"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9460a5dc184fa05d8eb635b687ad3220d02d2d23d6f49c3bf146aa71e427f423"
dependencies = [
"cached",
"cfg-if",
"gloo-net 0.2.6",
"itertools 0.12.1",
"js-sys",
"lazy_static",
"leptos 0.6.9",
"leptos_integration_utils 0.6.9",
"leptos_meta 0.6.9",
"linear-map",
"lru",
"once_cell",
"percent-encoding",
"regex",
"send_wrapper",
"serde",
"serde_json",
"serde_qs",
"thiserror",
"tracing",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]] [[package]]
name = "leptos_server" name = "leptos_server"
version = "0.5.4" version = "0.5.4"
@ -1882,10 +2274,26 @@ checksum = "272d018a5adf33d10ee57e6f0f83dccc305c68613cd207e8a653aeebd4cd5b4f"
dependencies = [ dependencies = [
"inventory", "inventory",
"lazy_static", "lazy_static",
"leptos_macro", "leptos_macro 0.5.4",
"leptos_reactive", "leptos_reactive 0.5.4",
"serde", "serde",
"server_fn", "server_fn 0.5.4",
"thiserror",
"tracing",
]
[[package]]
name = "leptos_server"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "654b6ff6a24e79977641b5214452373b1e12fdf4c8a563fadf656c139694b4b9"
dependencies = [
"inventory",
"lazy_static",
"leptos_macro 0.6.9",
"leptos_reactive 0.6.9",
"serde",
"server_fn 0.6.9",
"thiserror", "thiserror",
"tracing", "tracing",
] ]
@ -1912,13 +2320,14 @@ dependencies = [
"dotenv", "dotenv",
"futures", "futures",
"http 0.2.11", "http 0.2.11",
"icondata",
"lazy_static", "lazy_static",
"leptos", "leptos 0.6.9",
"leptos_actix", "leptos_actix",
"leptos_axum", "leptos_axum",
"leptos_icons", "leptos_icons",
"leptos_meta", "leptos_meta 0.6.9",
"leptos_router", "leptos_router 0.6.9",
"openssl", "openssl",
"pbkdf2", "pbkdf2",
"serde", "serde",
@ -2696,6 +3105,15 @@ 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 = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]]
name = "send_wrapper"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
dependencies = [
"futures-core",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.195" version = "1.0.195"
@ -2716,6 +3134,17 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "serde-wasm-bindgen"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b"
dependencies = [
"js-sys",
"serde",
"wasm-bindgen",
]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.195" version = "1.0.195"
@ -2797,7 +3226,7 @@ checksum = "cfed18dfcc8d9004579c40482c3419c07f60ffb9c5b250542edca99f508b0ce9"
dependencies = [ dependencies = [
"ciborium", "ciborium",
"const_format", "const_format",
"gloo-net", "gloo-net 0.2.6",
"inventory", "inventory",
"js-sys", "js-sys",
"lazy_static", "lazy_static",
@ -2808,12 +3237,43 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"serde_qs", "serde_qs",
"server_fn_macro_default", "server_fn_macro_default 0.5.4",
"syn 2.0.48", "syn 2.0.48",
"thiserror", "thiserror",
"xxhash-rust", "xxhash-rust",
] ]
[[package]]
name = "server_fn"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2955da1dc5fcd970c182ebf1089af6c5f19051e1f286a21f7b96490a49b7a531"
dependencies = [
"actix-web",
"bytes",
"ciborium",
"const_format",
"dashmap",
"futures",
"gloo-net 0.5.0",
"http 1.0.0",
"inventory",
"js-sys",
"once_cell",
"send_wrapper",
"serde",
"serde_json",
"serde_qs",
"server_fn_macro_default 0.6.9",
"thiserror",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"xxhash-rust",
]
[[package]] [[package]]
name = "server_fn_macro" name = "server_fn_macro"
version = "0.5.4" version = "0.5.4"
@ -2829,13 +3289,37 @@ dependencies = [
"xxhash-rust", "xxhash-rust",
] ]
[[package]]
name = "server_fn_macro"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adfdd051ef905fdb3da20942b0c52d536158d7489a724e14cc2fd47323e7ca91"
dependencies = [
"const_format",
"convert_case 0.6.0",
"proc-macro2",
"quote",
"syn 2.0.48",
"xxhash-rust",
]
[[package]] [[package]]
name = "server_fn_macro_default" name = "server_fn_macro_default"
version = "0.5.4" version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7256ba61dfadb220598db418376e7bc2a34b96df36c4dc48f24ffe161810fc0b" checksum = "7256ba61dfadb220598db418376e7bc2a34b96df36c4dc48f24ffe161810fc0b"
dependencies = [ dependencies = [
"server_fn_macro", "server_fn_macro 0.5.4",
"syn 2.0.48",
]
[[package]]
name = "server_fn_macro_default"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "060af1def72353a779fcc184c53e1965d3055a38b9e827f2259b2bff2d9c371e"
dependencies = [
"server_fn_macro 0.6.9",
"syn 2.0.48", "syn 2.0.48",
] ]
@ -3131,7 +3615,19 @@ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"toml_edit", "toml_edit 0.19.15",
]
[[package]]
name = "toml"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.22.9",
] ]
[[package]] [[package]]
@ -3153,7 +3649,20 @@ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"winnow", "winnow 0.5.37",
]
[[package]]
name = "toml_edit"
version = "0.22.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow 0.6.5",
] ]
[[package]] [[package]]
@ -3508,6 +4017,19 @@ version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
[[package]]
name = "wasm-streams"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129"
dependencies = [
"futures-util",
"js-sys",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.66" version = "0.3.66"
@ -3624,6 +4146,15 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "winnow"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "winreg" name = "winreg"
version = "0.50.0" version = "0.50.0"

View File

@ -13,23 +13,14 @@ actix-web = { version = "4", optional = true, features = ["macros"] }
console_error_panic_hook = "0.1" console_error_panic_hook = "0.1"
cfg-if = "1" cfg-if = "1"
http = "0.2" http = "0.2"
leptos = { version = "0.5", features = ["nightly"] } leptos = { version = "0.6", features = ["nightly"] }
leptos_meta = { version = "0.5", features = ["nightly"] } leptos_meta = { version = "0.6", features = ["nightly"] }
leptos_actix = { version = "0.5", optional = true } leptos_actix = { version = "0.6", optional = true }
leptos_axum = { version = "0.5", optional = true } leptos_axum = { version = "0.5", optional = true }
leptos_router = { version = "0.5", features = ["nightly"] } leptos_router = { version = "0.6", features = ["nightly"] }
wasm-bindgen = "=0.2.89" wasm-bindgen = "=0.2.89"
leptos_icons = { version = "0.1.0", default_features = false, features = [ leptos_icons = { version = "0.3.0" }
"BsPlayFill", icondata = { version = "0.3.0" }
"BsPauseFill",
"BsSkipStartFill",
"BsSkipEndFill",
"RiPlayListMediaFill",
"CgTrash",
"IoReturnUpBackSharp",
"AiEyeFilled",
"AiEyeInvisibleFilled"
] }
dotenv = { version = "0.15.0", optional = true } dotenv = { version = "0.15.0", optional = true }
diesel = { version = "2.1.4", features = ["postgres", "r2d2", "time"], optional = true } diesel = { version = "2.1.4", features = ["postgres", "r2d2", "time"], optional = true }
lazy_static = { version = "1.4.0", optional = true } lazy_static = { version = "1.4.0", optional = true }
@ -84,7 +75,7 @@ panic = "abort"
[package.metadata.leptos] [package.metadata.leptos]
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name # The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
output-name = "leptos_start" output-name = "libretunes"
# The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup. # The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup.
site-root = "target/site" site-root = "target/site"
# The site-root relative folder where all compiled output (JS, WASM and CSS) is written # The site-root relative folder where all compiled output (JS, WASM and CSS) is written

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2022 henrik Copyright (c) 2023-2024 The LibreTunes Authors
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 121 KiB

22
cicd/add-dns.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
set -e
ZONE_ID=$1
RECORD_NAME=$2
RECORD_COMMENT=$3
API_TOKEN=$4
TUNNEL_ID=$5
curl --request POST --silent \
--url https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $API_TOKEN" \
--data '{
"content": "'$TUNNEL_ID'.cfargotunnel.com",
"name": "'$RECORD_NAME'",
"comment": "'$RECORD_COMMENT'",
"proxied": true,
"type": "CNAME",
"ttl": 1
}' \

19
cicd/create-tunnel-config.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
set -e
SERVICE=$1
HOSTNAME=$2
TUNNEL_ID=$3
echo "Creating tunnel config for $HOSTNAME"
cat <<EOF > cloudflared-tunnel-config.yml
tunnel: $TUNNEL_ID
credentials-file: /etc/cloudflared/auth.json
ingress:
- hostname: $HOSTNAME
service: $SERVICE
- service: http_status:404
EOF

View File

@ -0,0 +1,55 @@
version: '3'
services:
cloudflare:
image: cloudflare/cloudflared:latest
command: tunnel run
volumes:
- cloudflared-config:/etc/cloudflared:ro
libretunes:
image: registry.mregirouard.com/libretunes/libretunes:${LIBRETUNES_VERSION}
environment:
REDIS_URL: redis://redis:6379
POSTGRES_HOST: postgres
POSTGRES_USER: libretunes
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: libretunes
volumes:
- libretunes-audio:/site/audio
depends_on:
- redis
- postgres
restart: always
redis:
image: redis:latest
volumes:
- libretunes-redis:/data
restart: always
healthcheck:
test: ["CMD-SHELL", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
postgres:
image: postgres:latest
environment:
POSTGRES_USER: libretunes
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: libretunes
volumes:
- libretunes-postgres:/var/lib/postgresql/data
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U libretunes"]
interval: 10s
timeout: 5s
retries: 5
volumes:
cloudflared-config:
libretunes-audio:
libretunes-redis:
libretunes-postgres:

22
cicd/remove-dns.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
set -e
ZONE_ID=$1
RECORD_NAME=$2
RECORD_COMMENT=$3
API_TOKEN=$4
RECORD_ID=$(
curl --request GET --silent \
--url "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$RECORD_NAME&comment=$RECORD_COMMENT" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $API_TOKEN" \
| jq -r '.result[0].id')
echo "Deleting DNS record ID $RECORD_ID"
curl --request DELETE --silent \
--url "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $API_TOKEN"

View File

@ -16,7 +16,7 @@ pub fn App() -> impl IntoView {
view! { view! {
// injects a stylesheet into the document <head> // injects a stylesheet into the document <head>
// id=leptos means cargo-leptos will hot-reload this stylesheet // id=leptos means cargo-leptos will hot-reload this stylesheet
<Stylesheet id="leptos" href="/pkg/leptos_start.css"/> <Stylesheet id="leptos" href="/pkg/libretunes.css"/>
// sets the document title // sets the document title
<Title text="LibreTunes"/> <Title text="LibreTunes"/>
@ -44,7 +44,7 @@ pub fn App() -> impl IntoView {
/// Renders the home page of your application. /// Renders the home page of your application.
#[component] #[component]
fn HomePage() -> impl IntoView { fn HomePage() -> impl IntoView {
let mut play_status = PlayStatus::default(); let play_status = PlayStatus::default();
let play_status = create_rw_signal(play_status); let play_status = create_rw_signal(play_status);
view! { view! {

View File

@ -1,4 +1,5 @@
use leptos::*; use leptos::*;
use crate::models::User; use crate::models::User;
/// Create a new user and log them in /// Create a new user and log them in
@ -11,6 +12,7 @@ pub async fn signup(new_user: User) -> Result<(), ServerFnError> {
use leptos_actix::extract; use leptos_actix::extract;
use actix_web::{HttpMessage, HttpRequest}; use actix_web::{HttpMessage, HttpRequest};
use actix_identity::Identity; use actix_identity::Identity;
use leptos::server_fn::error::NoCustomError;
// Ensure the user has no id // Ensure the user has no id
let new_user = User { let new_user = User {
@ -19,13 +21,17 @@ pub async fn signup(new_user: User) -> Result<(), ServerFnError> {
}; };
create_user(&new_user).await create_user(&new_user).await
.map_err(|e| ServerFnError::ServerError(format!("Error creating user: {}", e)))?; .map_err(|e| ServerFnError::<NoCustomError>::ServerError(format!("Error creating user: {}", e)))?;
extract(|request: HttpRequest| async move { match extract::<HttpRequest>().await {
Identity::login(&request.extensions(), new_user.username.clone()) Ok(request) => {
}).await??; match Identity::login(&request.extensions(), new_user.username.clone()) {
Ok(_) => Ok(()),
Ok(()) Err(e) => Err(ServerFnError::<NoCustomError>::ServerError(format!("Error logging in user: {}", e))),
}
},
Err(e) => Err(ServerFnError::<NoCustomError>::ServerError(format!("Error getting request: {}", e))),
}
} }
/// Log a user in /// Log a user in
@ -37,20 +43,25 @@ pub async fn login(username_or_email: String, password: String) -> Result<bool,
use actix_web::{HttpMessage, HttpRequest}; use actix_web::{HttpMessage, HttpRequest};
use actix_identity::Identity; use actix_identity::Identity;
use leptos_actix::extract; use leptos_actix::extract;
use leptos::server_fn::error::NoCustomError;
let possible_user = validate_user(username_or_email, password).await let possible_user = validate_user(username_or_email, password).await
.map_err(|e| ServerFnError::ServerError(format!("Error validating user: {}", e)))?; .map_err(|e| ServerFnError::<NoCustomError>::ServerError(format!("Error validating user: {}", e)))?;
let user = match possible_user { let user = match possible_user {
Some(user) => user, Some(user) => user,
None => return Ok(false) None => return Ok(false)
}; };
extract(|request: HttpRequest| async move { match extract::<HttpRequest>().await {
Identity::login(&request.extensions(), user.username.clone()) Ok(request) => {
}).await??; match Identity::login(&request.extensions(), user.username.clone()) {
Ok(_) => Ok(true),
Ok(true) Err(e) => Err(ServerFnError::<NoCustomError>::ServerError(format!("Error logging in user: {}", e))),
}
}
Err(e) => Err(ServerFnError::<NoCustomError>::ServerError(format!("Error getting request: {}", e))),
}
} }
/// Log a user out /// Log a user out
@ -59,12 +70,13 @@ pub async fn login(username_or_email: String, password: String) -> Result<bool,
pub async fn logout() -> Result<(), ServerFnError> { pub async fn logout() -> Result<(), ServerFnError> {
use leptos_actix::extract; use leptos_actix::extract;
use actix_identity::Identity; use actix_identity::Identity;
use leptos::server_fn::error::NoCustomError;
extract(|user: Option<Identity>| async move { match extract::<Option<Identity>>().await {
if let Some(user) = user { Ok(Some(user)) => user.logout(),
user.logout(); Ok(None) => {},
} Err(e) => return Err(ServerFnError::<NoCustomError>::ServerError(format!("Error getting user: {}", e))),
}).await?; };
Ok(()) Ok(())
} }

View File

@ -1,8 +1,8 @@
use cfg_if::cfg_if; use cfg_if::cfg_if;
use leptos::logging::log;
cfg_if! { cfg_if! {
if #[cfg(feature = "ssr")] { if #[cfg(feature = "ssr")] {
use leptos::logging::log;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use std::env; use std::env;

View File

@ -28,7 +28,6 @@ if #[cfg(feature = "hydrate")] {
#[wasm_bindgen] #[wasm_bindgen]
pub fn hydrate() { pub fn hydrate() {
use app::*; use app::*;
use leptos::*;
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();

View File

@ -1,5 +1,4 @@
use std::time::SystemTime; use std::time::SystemTime;
use std::error::Error;
use time::Date; use time::Date;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -9,6 +8,7 @@ cfg_if! {
if #[cfg(feature = "ssr")] { if #[cfg(feature = "ssr")] {
use diesel::prelude::*; use diesel::prelude::*;
use crate::database::PgPooledConn; use crate::database::PgPooledConn;
use std::error::Error;
} }
} }

View File

@ -1,9 +1,8 @@
use crate::auth::login; use crate::auth::login;
use leptos::leptos_dom::*; use leptos::leptos_dom::*;
use leptos::*; use leptos::*;
use leptos_icons::AiIcon::*;
use leptos_icons::IoIcon::*;
use leptos_icons::*; use leptos_icons::*;
use icondata;
#[component] #[component]
pub fn Login() -> impl IntoView { pub fn Login() -> impl IntoView {
@ -42,7 +41,7 @@ pub fn Login() -> impl IntoView {
view! { view! {
<div class="auth-page-container"> <div class="auth-page-container">
<div class="login-container"> <div class="login-container">
<a class="return" href="/"><Icon icon=Icon::from(IoReturnUpBackSharp) /></a> <a class="return" href="/"><Icon icon=icondata::IoReturnUpBackSharp /></a>
<div class="header"> <div class="header">
<h1>LibreTunes</h1> <h1>LibreTunes</h1>
</div> </div>
@ -70,11 +69,11 @@ pub fn Login() -> impl IntoView {
<Show <Show
when=move || {show_password() == false} when=move || {show_password() == false}
fallback=move || view!{ <button on:click=toggle_password class="login-password-visibility"> fallback=move || view!{ <button on:click=toggle_password class="login-password-visibility">
<Icon icon=Icon::from(AiEyeInvisibleFilled) /> <Icon icon=icondata::AiEyeInvisibleFilled />
</button> /> } </button> /> }
> >
<button on:click=toggle_password class="login-password-visibility"> <button on:click=toggle_password class="login-password-visibility">
<Icon icon=Icon::from(AiEyeFilled) /> <Icon icon=icondata::AiEyeFilled />
</button> </button>
</Show> </Show>

View File

@ -1,11 +1,9 @@
use crate::auth::signup; use crate::auth::signup;
use crate::models::User; use crate::models::User;
use leptos::ev::input;
use leptos::leptos_dom::*; use leptos::leptos_dom::*;
use leptos::*; use leptos::*;
use leptos_icons::AiIcon::*;
use leptos_icons::IoIcon::*;
use leptos_icons::*; use leptos_icons::*;
use icondata;
#[component] #[component]
pub fn Signup() -> impl IntoView { pub fn Signup() -> impl IntoView {
@ -15,8 +13,6 @@ pub fn Signup() -> impl IntoView {
let (show_password, set_show_password) = create_signal(false); let (show_password, set_show_password) = create_signal(false);
let navigate = leptos_router::use_navigate();
let toggle_password = move |_| { let toggle_password = move |_| {
set_show_password.update(|show_password| *show_password = !*show_password); set_show_password.update(|show_password| *show_password = !*show_password);
log!("showing password"); log!("showing password");
@ -49,7 +45,7 @@ pub fn Signup() -> impl IntoView {
view! { view! {
<div class="auth-page-container"> <div class="auth-page-container">
<div class="signup-container"> <div class="signup-container">
<a class="return" href="/"><Icon icon=Icon::from(IoReturnUpBackSharp) /></a> <a class="return" href="/"><Icon icon=icondata::IoReturnUpBackSharp /></a>
<div class="header"> <div class="header">
<h1>LibreTunes</h1> <h1>LibreTunes</h1>
</div> </div>
@ -86,10 +82,10 @@ pub fn Signup() -> impl IntoView {
<i></i> <i></i>
<Show <Show
when=move || {show_password() == false} when=move || {show_password() == false}
fallback=move || view!{ <button on:click=toggle_password class="password-visibility"> <Icon icon=Icon::from(AiEyeInvisibleFilled) /></button> /> } fallback=move || view!{ <button on:click=toggle_password class="password-visibility"> <Icon icon=icondata::AiEyeInvisibleFilled /></button> /> }
> >
<button on:click=toggle_password class="password-visibility"> <button on:click=toggle_password class="password-visibility">
<Icon icon=Icon::from(AiEyeFilled) /> <Icon icon=icondata::AiEyeFilled />
</button> </button>
</Show> </Show>
</div> </div>

View File

@ -1,12 +1,8 @@
use std::time::Duration;
use crate::playstatus::PlayStatus; use crate::playstatus::PlayStatus;
use leptos::ev::MouseEvent; use leptos::ev::MouseEvent;
use leptos::html::{Audio, Div}; use leptos::html::{Audio, Div};
use leptos::leptos_dom::*; use leptos::leptos_dom::*;
use leptos::*; use leptos::*;
use leptos_icons::BsIcon::*;
use leptos_icons::RiIcon::*;
use leptos_icons::*; use leptos_icons::*;
/// Width and height of the forward/backward skip buttons /// Width and height of the forward/backward skip buttons
@ -195,9 +191,9 @@ fn PlayControls(status: RwSignal<PlayStatus>) -> impl IntoView {
let icon = Signal::derive(move || { let icon = Signal::derive(move || {
status.with(|status| { status.with(|status| {
if status.playing { if status.playing {
Icon::from(BsPauseFill) icondata::BsPauseFill
} else { } else {
Icon::from(BsPlayFill) icondata::BsPlayFill
} }
}) })
}); });
@ -206,7 +202,7 @@ fn PlayControls(status: RwSignal<PlayStatus>) -> impl IntoView {
<div class="playcontrols" align="center"> <div class="playcontrols" align="center">
<button on:click=skip_back on:mousedown=prevent_focus> <button on:click=skip_back on:mousedown=prevent_focus>
<Icon class="controlbtn" width=SKIP_BTN_SIZE height=SKIP_BTN_SIZE icon=Icon::from(BsSkipStartFill) /> <Icon class="controlbtn" width=SKIP_BTN_SIZE height=SKIP_BTN_SIZE icon=icondata::BsSkipStartFill />
</button> </button>
<button on:click=toggle_play on:mousedown=prevent_focus> <button on:click=toggle_play on:mousedown=prevent_focus>
@ -214,7 +210,7 @@ fn PlayControls(status: RwSignal<PlayStatus>) -> impl IntoView {
</button> </button>
<button on:click=skip_forward on:mousedown=prevent_focus> <button on:click=skip_forward on:mousedown=prevent_focus>
<Icon class="controlbtn" width=SKIP_BTN_SIZE height=SKIP_BTN_SIZE icon=Icon::from(BsSkipEndFill) /> <Icon class="controlbtn" width=SKIP_BTN_SIZE height=SKIP_BTN_SIZE icon=icondata::BsSkipEndFill />
</button> </button>
</div> </div>
@ -339,7 +335,7 @@ fn QueueToggle(status: RwSignal<PlayStatus>) -> impl IntoView {
view! { view! {
<div class="queue-toggle"> <div class="queue-toggle">
<button on:click=update_queue on:mousedown=prevent_focus> <button on:click=update_queue on:mousedown=prevent_focus>
<Icon class="controlbtn" width=QUEUE_BTN_SIZE height=QUEUE_BTN_SIZE icon=Icon::from(RiPlayListMediaFill) /> <Icon class="controlbtn" width=QUEUE_BTN_SIZE height=QUEUE_BTN_SIZE icon=icondata::RiPlayListMediaFill />
</button> </button>
</div> </div>
} }

View File

@ -4,7 +4,6 @@ use leptos::ev::MouseEvent;
use leptos::leptos_dom::*; use leptos::leptos_dom::*;
use leptos::*; use leptos::*;
use leptos_icons::*; use leptos_icons::*;
use leptos_icons::CgIcon::*;
use leptos::ev::DragEvent; use leptos::ev::DragEvent;
const RM_BTN_SIZE: &str = "2.5rem"; const RM_BTN_SIZE: &str = "2.5rem";
@ -106,7 +105,7 @@ pub fn Queue(status: RwSignal<PlayStatus>) -> impl IntoView {
<p>Playing</p> <p>Playing</p>
}> }>
<button on:click=move |_| remove_song(index) on:mousedown=prevent_focus> <button on:click=move |_| remove_song(index) on:mousedown=prevent_focus>
<Icon class="remove-song" width=RM_BTN_SIZE height=RM_BTN_SIZE icon=Icon::from(CgTrash) /> <Icon class="remove-song" width=RM_BTN_SIZE height=RM_BTN_SIZE icon=icondata::CgTrash />
</button> </button>
</Show> </Show>
</div> </div>

View File

@ -21,12 +21,13 @@ use crate::models::User;
#[cfg(feature = "ssr")] #[cfg(feature = "ssr")]
pub async fn find_user(username_or_email: String) -> Result<Option<User>, ServerFnError> { pub async fn find_user(username_or_email: String) -> Result<Option<User>, ServerFnError> {
use crate::schema::users::dsl::*; use crate::schema::users::dsl::*;
use leptos::server_fn::error::NoCustomError;
// Look for either a username or email that matches the input, and return an option with None if no user is found // Look for either a username or email that matches the input, and return an option with None if no user is found
let db_con = &mut get_db_conn(); let db_con = &mut get_db_conn();
let user = users.filter(username.eq(username_or_email.clone())).or_filter(email.eq(username_or_email)) let user = users.filter(username.eq(username_or_email.clone())).or_filter(email.eq(username_or_email))
.first::<User>(db_con).optional() .first::<User>(db_con).optional()
.map_err(|e| ServerFnError::ServerError(format!("Error getting user from database: {}", e)))?; .map_err(|e| ServerFnError::<NoCustomError>::ServerError(format!("Error getting user from database: {}", e)))?;
Ok(user) Ok(user)
} }
@ -36,13 +37,14 @@ pub async fn find_user(username_or_email: String) -> Result<Option<User>, Server
#[cfg(feature = "ssr")] #[cfg(feature = "ssr")]
pub async fn create_user(new_user: &User) -> Result<(), ServerFnError> { pub async fn create_user(new_user: &User) -> Result<(), ServerFnError> {
use crate::schema::users::dsl::*; use crate::schema::users::dsl::*;
use leptos::server_fn::error::NoCustomError;
let new_password = new_user.password.clone() let new_password = new_user.password.clone()
.ok_or(ServerFnError::ServerError(format!("No password provided for user {}", new_user.username)))?; .ok_or(ServerFnError::<NoCustomError>::ServerError(format!("No password provided for user {}", new_user.username)))?;
let salt = SaltString::generate(&mut OsRng); let salt = SaltString::generate(&mut OsRng);
let password_hash = Pbkdf2.hash_password(new_password.as_bytes(), &salt) let password_hash = Pbkdf2.hash_password(new_password.as_bytes(), &salt)
.map_err(|_| ServerFnError::ServerError("Error hashing password".to_string()))?.to_string(); .map_err(|_| ServerFnError::<NoCustomError>::ServerError("Error hashing password".to_string()))?.to_string();
let new_user = User { let new_user = User {
password: Some(password_hash), password: Some(password_hash),
@ -52,7 +54,7 @@ pub async fn create_user(new_user: &User) -> Result<(), ServerFnError> {
let db_con = &mut get_db_conn(); let db_con = &mut get_db_conn();
diesel::insert_into(users).values(&new_user).execute(db_con) diesel::insert_into(users).values(&new_user).execute(db_con)
.map_err(|e| ServerFnError::ServerError(format!("Error creating user: {}", e)))?; .map_err(|e| ServerFnError::<NoCustomError>::ServerError(format!("Error creating user: {}", e)))?;
Ok(()) Ok(())
} }
@ -61,8 +63,10 @@ pub async fn create_user(new_user: &User) -> Result<(), ServerFnError> {
/// Returns a Result with the user if the credentials are valid, None if not valid, or an error if there was a problem /// Returns a Result with the user if the credentials are valid, None if not valid, or an error if there was a problem
#[cfg(feature = "ssr")] #[cfg(feature = "ssr")]
pub async fn validate_user(username_or_email: String, password: String) -> Result<Option<User>, ServerFnError> { pub async fn validate_user(username_or_email: String, password: String) -> Result<Option<User>, ServerFnError> {
use leptos::server_fn::error::NoCustomError;
let db_user = find_user(username_or_email.clone()).await let db_user = find_user(username_or_email.clone()).await
.map_err(|e| ServerFnError::ServerError(format!("Error getting user from database: {}", e)))?; .map_err(|e| ServerFnError::<NoCustomError>::ServerError(format!("Error getting user from database: {}", e)))?;
// If the user is not found, return None // If the user is not found, return None
let db_user = match db_user { let db_user = match db_user {
@ -71,10 +75,10 @@ pub async fn validate_user(username_or_email: String, password: String) -> Resul
}; };
let db_password = db_user.password.clone() let db_password = db_user.password.clone()
.ok_or(ServerFnError::ServerError(format!("No password found for user {}", db_user.username)))?; .ok_or(ServerFnError::<NoCustomError>::ServerError(format!("No password found for user {}", db_user.username)))?;
let password_hash = PasswordHash::new(&db_password) let password_hash = PasswordHash::new(&db_password)
.map_err(|e| ServerFnError::ServerError(format!("Error hashing supplied password: {}", e)))?; .map_err(|e| ServerFnError::<NoCustomError>::ServerError(format!("Error hashing supplied password: {}", e)))?;
match Pbkdf2.verify_password(password.as_bytes(), &password_hash) { match Pbkdf2.verify_password(password.as_bytes(), &password_hash) {
Ok(()) => {}, Ok(()) => {},
@ -82,7 +86,7 @@ pub async fn validate_user(username_or_email: String, password: String) -> Resul
return Ok(None); return Ok(None);
}, },
Err(e) => { Err(e) => {
return Err(ServerFnError::ServerError(format!("Error verifying password: {}", e))); return Err(ServerFnError::<NoCustomError>::ServerError(format!("Error verifying password: {}", e)));
} }
} }