diff --git a/src/main.rs b/src/main.rs index 4cc134d..a2b853d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,7 +54,7 @@ async fn main() -> std::io::Result<()> { .wrap_fn(move |req, srv| { let secure = req.connection_info().scheme() == "https"; let https_url = format!("https://{}{}", req.connection_info().host(), req.uri().to_string()); - srv.call(req).map(move |res: Result| + srv.call(req).map(move |res: Result| { if force_https && !secure { Ok(ServiceResponse::new( res.unwrap().request().to_owned(), @@ -63,16 +63,21 @@ async fn main() -> std::io::Result<()> { } else { res } - ) + }) }) // Append trailing slash and remove double slashes .wrap(middleware::NormalizePath::default()) // Apply default headers for security - .wrap(middleware::DefaultHeaders::new() - .header("Referrer-Policy", "no-referrer") - .header("X-Content-Type-Options", "nosniff") - .header("X-Frame-Options", "DENY") - .header("Content-Security-Policy", "default-src 'none'; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none';")) + .wrap( + middleware::DefaultHeaders::new() + .header("Referrer-Policy", "no-referrer") + .header("X-Content-Type-Options", "nosniff") + .header("X-Frame-Options", "DENY") + .header( + "Content-Security-Policy", + "default-src 'none'; style-src 'self' 'unsafe-inline'; base-uri 'none'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none';", + ), + ) // Default service in case no routes match .default_service(web::get().to(|| utils::error("Nothing here".to_string()))) // Read static files diff --git a/src/proxy.rs b/src/proxy.rs index df1ca56..fcd571d 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -24,26 +24,24 @@ pub async fn handler(web::Path(b64): web::Path) -> Result let decoded = decode(b64).map(|bytes| String::from_utf8(bytes).unwrap_or_default()); match decoded { - Ok(media) => { - match Url::parse(media.as_str()) { - Ok(url) => { - let domain = url.domain().unwrap_or_default(); + Ok(media) => match Url::parse(media.as_str()) { + Ok(url) => { + let domain = url.domain().unwrap_or_default(); - if domains.contains(&domain) { - Client::default().get(media.replace("&", "&")).send().await.map_err(Error::from).map(|res| { - HttpResponse::build(res.status()) - .header("Cache-Control", "public, max-age=1209600, s-maxage=86400") - .header("Content-Length", res.headers().get("Content-Length").unwrap().to_owned()) - .header("Content-Type", res.headers().get("Content-Type").unwrap().to_owned()) - .streaming(res) - }) - } else { - Err(error::ErrorForbidden("Resource must be from Reddit")) - } + if domains.contains(&domain) { + Client::default().get(media.replace("&", "&")).send().await.map_err(Error::from).map(|res| { + HttpResponse::build(res.status()) + .header("Cache-Control", "public, max-age=1209600, s-maxage=86400") + .header("Content-Length", res.headers().get("Content-Length").unwrap().to_owned()) + .header("Content-Type", res.headers().get("Content-Type").unwrap().to_owned()) + .streaming(res) + }) + } else { + Err(error::ErrorForbidden("Resource must be from Reddit")) } - _ => Err(error::ErrorBadRequest("Can't parse base64 into URL")), } - } + _ => Err(error::ErrorBadRequest("Can't parse base64 into URL")), + }, _ => Err(error::ErrorBadRequest("Can't decode base64")), } } diff --git a/src/subreddit.rs b/src/subreddit.rs index bd8deda..ebad6c9 100644 --- a/src/subreddit.rs +++ b/src/subreddit.rs @@ -26,25 +26,44 @@ struct WikiTemplate { // SERVICES pub async fn page(req: HttpRequest) -> HttpResponse { - let path = format!("{}.json?{}", req.path(), req.query_string()); - let default = cookie(&req, "front_page"); + let subscribed = cookie(&req, "subscriptions"); + let front_page = cookie(&req, "front_page"); + let sort = req.match_info().get("sort").unwrap_or("hot").to_string(); + let sub = req .match_info() .get("sub") - .unwrap_or(if default.is_empty() { "popular" } else { default.as_str() }) - .to_string(); - let sort = req.match_info().get("sort").unwrap_or("hot").to_string(); + .map(String::from) + .unwrap_or(if front_page == "default" || front_page.is_empty() { + if subscribed.is_empty() { + "popular".to_string() + } else { + subscribed.to_owned() + } + } else { + front_page.to_owned() + }); + + let path = format!("/r/{}.json?{}", sub, req.query_string()); match fetch_posts(&path, String::new()).await { Ok((posts, after)) => { // If you can get subreddit posts, also request subreddit metadata - let sub = if !sub.contains('+') && sub != "popular" && sub != "all" { + let sub = if !sub.contains('+') && sub != subscribed && sub != "popular" && sub != "all" { + // Regular subreddit subreddit(&sub).await.unwrap_or_default() } else if sub.contains('+') { + // Multireddit Subreddit { name: sub, ..Subreddit::default() } + } else if sub == subscribed { + if req.path().starts_with("/r/") { + subreddit(&sub).await.unwrap_or_default() + } else { + Subreddit::default() + } } else { Subreddit::default() }; @@ -84,11 +103,13 @@ pub async fn subscriptions(req: HttpRequest) -> HttpResponse { if sub_list.is_empty() { res.del_cookie(&Cookie::build("subscriptions", "").path("/").finish()); } else { - res.cookie(Cookie::build("subscriptions", sub_list.join(",")) - .path("/") - .http_only(true) - .expires(OffsetDateTime::now_utc() + Duration::weeks(52)) - .finish(),); + res.cookie( + Cookie::build("subscriptions", sub_list.join("+")) + .path("/") + .http_only(true) + .expires(OffsetDateTime::now_utc() + Duration::weeks(52)) + .finish(), + ); } // Redirect back to subreddit diff --git a/src/utils.rs b/src/utils.rs index f8ad46e..1efea71 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -145,7 +145,7 @@ pub fn prefs(req: HttpRequest) -> Preferences { wide: cookie(&req, "wide"), hide_nsfw: cookie(&req, "hide_nsfw"), comment_sort: cookie(&req, "comment_sort"), - subs: cookie(&req, "subscriptions").split(",").map(String::from).filter(|s| s != "").collect(), + subs: cookie(&req, "subscriptions").split('+').map(String::from).filter(|s| s != "").collect(), } } diff --git a/static/style.css b/static/style.css index 8cebed1..53f3ed5 100644 --- a/static/style.css +++ b/static/style.css @@ -95,13 +95,23 @@ nav { nav * { color: var(--text); } nav #reddit, #code { color: var(--accent); } nav #logo { grid-area: logo; } -nav #links { grid-area: links; } -nav #version { opacity: 50%; vertical-align: -2px; } -nav #libreddit { vertical-align: -2px; } +nav #links { + grid-area: links; + margin-left: 10px; +} + +nav #version { + opacity: 50%; + vertical-align: -2px; + margin-right: 10px; +} + +nav #libreddit { + vertical-align: -2px; +} #settings_link { - margin-left: 10px; opacity: 0.8; } @@ -240,17 +250,18 @@ aside { margin-top: 20px; } -#sub_subscription > a { +#sub_subscription button { padding: 10px 20px; border-radius: 5px; + cursor: pointer; } -#sub_subscription > .add { +#subscribe { color: var(--foreground); background-color: var(--accent); } -#sub_subscription > .remove { +#unsubscribe { color: var(--text); background-color: var(--highlighted); } @@ -266,11 +277,10 @@ aside { box-sizing: border-box; font-size: 15px; display: inline-block; - margin-left: 10px; } #subscriptions > summary { - padding: 10px 20px 10px 15px; + padding: 8px 15px; } #sub_list { diff --git a/templates/settings.html b/templates/settings.html index 96e397c..a6d8470 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -21,7 +21,7 @@
diff --git a/templates/subreddit.html b/templates/subreddit.html index ee6ed93..ab80a03 100644 --- a/templates/subreddit.html +++ b/templates/subreddit.html @@ -127,9 +127,13 @@
{% if prefs.subs.contains(sub.name) %} - +
+ +
{% else %} - +
+ +
{% endif %}