diff --git a/Cargo.toml b/Cargo.toml index 2ef176b..d31366b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ axum = { version = "0.7", optional = true } axum-extra = { version = "0.9", features = ["cookie"], optional = true } time = { version = "0.3", optional = true } once_cell = { version = "1.19", optional = true } -surrealdb = { version = "2.0", features = [], optional = true } +surrealdb = { version = "2.0", features = ["kv-rocksdb"], optional = true } thiserror = { version = "1.0" } csv = { version = "1.3", optional = true } @@ -29,5 +29,5 @@ manganis = "0.2" [features] default = [] -server = [ "dioxus/axum", "tokio", "axum", "axum-extra", "time", "once_cell", "surrealdb/kv-rocksdb", "csv" ] -web = ["dioxus/web", "surrealdb"] +server = [ "dioxus/axum", "tokio", "axum", "axum-extra", "time", "once_cell", "surrealdb", "csv" ] +web = ["dioxus/web"] diff --git a/src/util/model/member.rs b/src/util/model/member.rs index 3f184b9..a0e8596 100644 --- a/src/util/model/member.rs +++ b/src/util/model/member.rs @@ -1,5 +1,5 @@ #[cfg(feature = "server")] -use crate::util::surrealdb::DB; +use crate::util::surrealdb::{thing_to_string, DB}; use serde::{Deserialize, Serialize}; #[cfg(feature = "server")] @@ -7,6 +7,7 @@ mod migration; #[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)] pub struct Member { + #[cfg_attr(feature = "server", serde(deserialize_with = "thing_to_string"))] pub id: String, pub name: Name, pub hours: Vec, @@ -31,7 +32,7 @@ pub struct MembersMigration { #[cfg(feature = "server")] impl Member { pub async fn fetch_all() -> Result, surrealdb::Error> { - let mut res = DB.query("SELECT record::id(id) as id, name.first, name.full, hours, groups, diploma, registration_token FROM member").await?; + let mut res = DB.query("SELECT id, name.first, name.full, hours, groups, diploma, registration_token FROM member").await?; let members: Vec = res.take(0)?; @@ -42,7 +43,7 @@ impl Member { registration_token: String, ) -> Result, surrealdb::Error> { let mut res = DB - .query("SELECT record::id(id) as id, name.first, name.full, hours, groups, diploma, registration_token FROM ONLY member WHERE registration_token = $registration_token LIMIT 1") + .query("SELECT id, name.first, name.full, hours, groups, diploma, registration_token FROM ONLY member WHERE registration_token = $registration_token LIMIT 1") .bind(("registration_token", registration_token)) .await?; @@ -54,7 +55,7 @@ impl Member { pub async fn fetch_from_user(user_id: String) -> Result, crate::Error> { let mut res = DB .query( - "SELECT VALUE array::map(->user_to_member->member.*, |$obj| {{ id: record::id($obj.id), }}) FROM ONLY type::thing('user', $user_id)", + "SELECT VALUE ->user_to_member->member.* FROM ONLY type::thing('user', $user_id)", ) .bind(("user_id", user_id)) .await?; diff --git a/src/util/model/session.rs b/src/util/model/session.rs index 3b92313..daf0481 100644 --- a/src/util/model/session.rs +++ b/src/util/model/session.rs @@ -1,5 +1,5 @@ #[cfg(feature = "server")] -use crate::util::surrealdb::DB; +use crate::util::surrealdb::{thing_to_string, DB}; use dioxus::prelude::*; use serde::{Deserialize, Serialize}; @@ -8,7 +8,9 @@ use super::user::User; #[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)] pub struct Session { + #[cfg_attr(feature = "server", serde(deserialize_with = "thing_to_string"))] id: String, + #[cfg_attr(feature = "server", serde(deserialize_with = "thing_to_string"))] user_id: String, expires: i64, token: String, @@ -18,7 +20,7 @@ pub struct Session { impl Session { pub async fn new(user_id: String) -> Result { let mut res = DB - .query("CREATE ONLY session SET user = type::thing('user', $user_id) RETURN record::id(id) as id, record::id(user) as user_id, time::unix(expires) as expires, token;") + .query("CREATE ONLY session SET user = type::thing('user', $user_id) RETURN id, user as user_id, time::unix(expires) as expires, token;") .bind(("user_id", user_id)) .await?; @@ -59,7 +61,9 @@ impl Session { pub async fn fetch_user_from_token(session_token: String) -> Result { let mut res = DB - .query("SELECT record::id(user) as id, user.email as email FROM session WHERE token = $session_token") + .query( + "SELECT user as id, user.email as email FROM session WHERE token = $session_token", + ) .bind(("session_token", session_token)) .await?; diff --git a/src/util/model/user.rs b/src/util/model/user.rs index 7e9dc07..72c1304 100644 --- a/src/util/model/user.rs +++ b/src/util/model/user.rs @@ -1,12 +1,13 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "server")] -use crate::util::surrealdb::DB; +use crate::util::surrealdb::{thing_to_string, DB}; #[cfg(feature = "server")] use surrealdb::sql::statements::{BeginStatement, CommitStatement}; #[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)] pub struct User { + #[cfg_attr(feature = "server", serde(deserialize_with = "thing_to_string"))] pub id: String, pub email: String, password: Option, @@ -21,7 +22,7 @@ impl User { ) -> Result { // Create user record let mut transaction = DB.query(BeginStatement::default()) - .query("let $user = CREATE ONLY user SET email = $email, password = crypto::argon2::generate($password) RETURN record::id(id) as id, email;") + .query("let $user = CREATE ONLY user SET email = $email, password = crypto::argon2::generate($password) RETURN id, email;") .bind(("email", email)) .bind(("password", password)); @@ -49,7 +50,7 @@ impl User { password: String, ) -> Result { let mut res = DB - .query("SELECT VALUE record::id(id) as id FROM user WHERE email = $email AND crypto::argon2::compare(password, $password)") + .query("SELECT VALUE id FROM user WHERE email = $email AND crypto::argon2::compare(password, $password)") .bind(("email", email)).bind(("password", password)) .await?; diff --git a/src/util/surrealdb.rs b/src/util/surrealdb.rs index 21cfb74..8eb9c4a 100644 --- a/src/util/surrealdb.rs +++ b/src/util/surrealdb.rs @@ -1,9 +1,19 @@ use once_cell::sync::Lazy; +use serde::{Deserialize, Deserializer}; use surrealdb::engine::local::{Db, RocksDb}; +use surrealdb::sql::Thing; use surrealdb::Surreal; pub static DB: Lazy> = Lazy::new(|| Surreal::init()); +pub fn thing_to_string<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let t = Thing::deserialize(deserializer)?; + Ok(t.id.to_raw()) +} + pub async fn initialize() -> surrealdb::Result<()> { DB.connect::("./database").await?;