diff --git a/src/graphql/mod.rs b/src/graphql/mod.rs index ee4b8d6..63b22a2 100644 --- a/src/graphql/mod.rs +++ b/src/graphql/mod.rs @@ -4,10 +4,16 @@ use rocket::response::content::RawHtml; use rocket::State; use rocket::request::{FromRequest, Outcome, Request}; use rocket::http::Status; +use std::env; +use once_cell::sync::Lazy; // use crate::account::account::{read_basic_auth_token, read_bearer_auth_token}; use crate::nnid::oauth::TokenData; use crate::Pool; +pub static API_KEY: Lazy = Lazy::new(|| { + env::var("GRAPHQL_API_KEY").expect("GRAPHQL_API_KEY not set") +}); + #[rocket::async_trait] impl<'r> FromRequest<'r> for Context { type Error = (); @@ -57,6 +63,15 @@ struct UserInfo { mii_data: String, } +#[derive(GraphQLObject)] +#[graphql(description = "User information from a username")] +struct UserInfoWithPId { + username: String, + account_level: i32, + nex_password: String, + mii_data: String, + pid: i32, +} pub struct Query; @@ -78,7 +93,7 @@ impl Query { "select * from tokens where pid = $1 and token_id = $2 and random = $3", data.pid, data.token_id, data.random ). - fetch_one(&context.0).await.ok()?; + fetch_one(&context.pool).await.ok()?; Some(TokenInfo{ pid: data.pid, @@ -103,7 +118,7 @@ impl Query { "SELECT username, account_level, nex_password, mii_data FROM users WHERE pid = $1", data.pid ) - .fetch_one(&context.0) + .fetch_one(&context.pool) .await .ok() { Some(user) => user, @@ -122,11 +137,8 @@ impl Query { } async fn user_by_pid(pid: i32, context: &Context) -> Option { - // Expected API key (could also be in an env var) - const EXPECTED_KEY: &str = "your-secret-api-key"; - - if context.api_key.as_deref() != Some(EXPECTED_KEY) { - eprintln!("Rejected request due to missing or invalid API key"); + if context.api_key.as_deref() != Some(&*API_KEY) { + eprintln!("Rejected request: invalid API key"); return None; } @@ -146,7 +158,28 @@ impl Query { }) } + async fn user_by_username(username: String, context: &Context) -> Option { + if context.api_key.as_deref() != Some(&*API_KEY) { + eprintln!("Rejected request: invalid API key"); + return None; + } + let user = sqlx::query!( + "SELECT pid, username, account_level, nex_password, mii_data FROM users WHERE username = $1", + username, + ) + .fetch_one(&context.pool) + .await + .ok()?; + + Some(UserInfoWithPId { + username: user.username, + account_level: user.account_level, + nex_password: user.nex_password, + mii_data: user.mii_data, + pid: user.pid, + }) + } } @@ -179,18 +212,18 @@ pub fn playground() -> RawHtml { #[rocket::get("/graphql?")] pub async fn get_graphql( - db: &State, request: juniper_rocket::GraphQLRequest, schema: &State, + context: Context ) -> juniper_rocket::GraphQLResponse { - request.execute(schema, db).await + request.execute(schema, &context).await } #[rocket::post("/graphql", data = "")] pub async fn post_graphql( - db: &State, request: juniper_rocket::GraphQLRequest, schema: &State, + context: Context ) -> juniper_rocket::GraphQLResponse { - request.execute(schema, db).await -} \ No newline at end of file + request.execute(schema, &context).await +}