diff --git a/Cargo.lock b/Cargo.lock index b12ddda..dbf40d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2512,6 +2512,7 @@ dependencies = [ "rocket_codegen 0.5.0-rc.3", "rocket_http 0.5.0-rc.3", "serde", + "serde_json", "state 0.5.3", "tempfile", "time 0.3.21", diff --git a/Cargo.toml b/Cargo.toml index 1695f1e..9f4d614 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ dotenv = "0.15.0" gettext = "0.4.0" poise = "0.5.5" reqwest = "0.11.18" -rocket = { version = "=0.5.0-rc.3", features = ["secrets"] } +rocket = { version = "=0.5.0-rc.3", features = ["secrets", "json"] } rocket_contrib = { version = "0.4.11", features = ["templates"] } rocket_dyn_templates = { version = "0.1.0-rc.3", features = ["tera"] } sass-rocket-fairing = "0.2.0" diff --git a/src/cookies.rs b/src/cookies.rs index 31858f1..dd49781 100644 --- a/src/cookies.rs +++ b/src/cookies.rs @@ -9,3 +9,4 @@ pub mod user { pub const USER_AVATAR_COOKIE: &str = "user_avatar"; } pub const LANG_COOKIE: &str = "lang"; +pub const WELCOMED_COOKIE: &str = "welcomed"; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 5ae91f2..ef96f4c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,7 +42,7 @@ async fn rocket() -> _ { .manage(http) .mount( "/", - routes![get_challenge, login, post_login, success, logout, testing], + routes![get_challenge, get_guilds, login, post_login, success, logout, testing], ) .mount("/css", FileServer::from(relative!("styles/css"))) .mount("/", FileServer::from(relative!("static")).rank(1)) diff --git a/src/routes/get_guilds.rs b/src/routes/get_guilds.rs new file mode 100644 index 0000000..f05d0d4 --- /dev/null +++ b/src/routes/get_guilds.rs @@ -0,0 +1,35 @@ +use std::collections::HashMap; + +use poise::serenity_prelude::Http; +use rocket::{http::{CookieJar, Status}, State}; +use rocket::serde::json::Json; + +use crate::{cookies::user::USER_ID_COOKIE, models::Settings}; + +// TODO: Incrementally send guilds +#[get("/get_guilds")] +pub async fn get_guilds( + cookies: &CookieJar<'_>, + settings: &State, + http: &State, +) -> Result>, Status> { + let user_id: u64 = match cookies.get_private(USER_ID_COOKIE) { + Some(id) => match id.value().parse() { + Ok(id) => id, + Err(_) => return Err(Status::BadRequest), + }, + None => return Err(Status::Unauthorized), + }; + Ok(Json({ + let mut guild_statuses = HashMap::with_capacity(settings.guilds.len()); + for guild in &settings.guilds { + guild_statuses.insert(guild.id, { + if guild.hidden { + continue; + } + http.get_member(guild.id, user_id).await.is_ok() + }); + } + guild_statuses + })) +} diff --git a/src/routes/login.rs b/src/routes/login.rs index 910de68..b0de556 100644 --- a/src/routes/login.rs +++ b/src/routes/login.rs @@ -6,7 +6,7 @@ use rocket::response::Redirect; pub fn login() -> Redirect { Redirect::to(format!( // Switch from response_type=code to response_type=token from URL generator - "https://discord.com/api/oauth2/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=token&scope=identify%20guilds.join%20guilds", + "https://discord.com/api/oauth2/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=token&scope=identify", client_id = env::var("CLIENT_ID").unwrap(), redirect_uri = format!("{}success", env::var("DOMAIN").unwrap()), )) diff --git a/src/routes/mod.rs b/src/routes/mod.rs index b2e2e50..ca7164a 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -2,6 +2,10 @@ mod _get_challenge; pub use _get_challenge::get_challenge; +#[path = "get_guilds.rs"] +mod _get_guilds; +pub use _get_guilds::get_guilds; + #[path = "login.rs"] mod _login; pub use _login::login; diff --git a/src/routes/post_login.rs b/src/routes/post_login.rs index 7be5462..b5d389e 100644 --- a/src/routes/post_login.rs +++ b/src/routes/post_login.rs @@ -5,7 +5,7 @@ use rocket::{ response::Redirect, }; -use crate::{cookies::token::TOKEN_EXPIRE_COOKIE, models::User}; +use crate::{cookies::{token::TOKEN_EXPIRE_COOKIE, WELCOMED_COOKIE}, models::User}; #[derive(FromForm)] pub struct Login<'r> { @@ -17,7 +17,7 @@ pub struct Login<'r> { #[post("/login", data = "")] pub async fn post_login(login: Form>, cookies: &CookieJar<'_>) -> Redirect { - if (login.token_type != "Bearer" || login.scope != "guilds.join+identify+guilds") + if (login.token_type != "Bearer" || login.scope.split("+").any(|scope| scope == "identify")) && User::init(login.access_token, cookies).await.is_ok() { cookies.add(Cookie::new( @@ -26,6 +26,7 @@ pub async fn post_login(login: Form>, cookies: &CookieJar<'_>) -> Redi .timestamp() .to_string(), )); + cookies.remove(Cookie::named(WELCOMED_COOKIE)); } Redirect::to("/") } diff --git a/styles/sass/style.scss b/styles/sass/style.scss index 925bc2f..63c91d7 100644 --- a/styles/sass/style.scss +++ b/styles/sass/style.scss @@ -164,14 +164,20 @@ a { flex-grow: 1; align-items: center; } - a { + .joinButton { + display: inline; background: seagreen; color: white; + font: inherit; font-weight: bold; border: none; outline: none; padding: 0.25em 0.5em 0.25em 0.5em; border-radius: 2px; + + &:disabled { + background: gray; + } } } .recommended { @@ -194,4 +200,9 @@ a { } } } +} + +.icon { + height: 1.5em; + vertical-align: middle; } \ No newline at end of file diff --git a/templates/index.html.tera b/templates/index.html.tera index c7925aa..d59faee 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -9,7 +9,9 @@ + {% if user %} {% include "modal" %} + {% endif %}
@@ -36,7 +51,7 @@ {% endif %}