Skip to content

Commit

Permalink
Make restore properly add new subscriptions/filters cookies and delet…
Browse files Browse the repository at this point in the history
…e old unused subscriptions/filters cookies
  • Loading branch information
ButteredCats committed Oct 13, 2024
1 parent 69b7450 commit 2657be2
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 2 deletions.
116 changes: 115 additions & 1 deletion src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::HashMap;

// CRATES
use crate::server::ResponseExt;
use crate::subreddit::join_until_size_limit;
use crate::utils::{redirect, template, Preferences};
use cookie::Cookie;
use futures_lite::StreamExt;
Expand Down Expand Up @@ -116,7 +117,7 @@ fn set_cookies_method(req: Request<Body>, remove_cookies: bool) -> Response<Body

let mut response = redirect(&path);

for name in [PREFS.to_vec(), vec!["subscriptions", "filters"]].concat() {
for name in PREFS {
match form.get(name) {
Some(value) => response.insert_cookie(
Cookie::build((name.to_owned(), value.clone()))
Expand All @@ -133,6 +134,119 @@ fn set_cookies_method(req: Request<Body>, remove_cookies: bool) -> Response<Body
};
}

// Get subscriptions/filters to restore from query string
let subscriptions = form.get("subscriptions");
let filters = form.get("filters");

// We can't search through the cookies directly like in subreddit.rs, so instead we have to make a string out of the request's headers to search through
let cookies_string = parts
.headers
.get("cookie")
.map(|hv| hv.to_str().unwrap_or("").to_string()) // Return String
.unwrap_or_else(String::new); // Return an empty string if None

// If there are subscriptions to restore set them and delete any old subscriptions cookies, otherwise delete them all
if subscriptions.is_some() {
let sub_list: Vec<String> = subscriptions.expect("Subscriptions").split('+').map(str::to_string).collect();

// Start at 0 to keep track of what number we need to start deleting old subscription cookies from
let mut subscriptions_number_to_delete_from = 0;

// Starting at 0 so we handle the subscription cookie without a number first
for (subscriptions_number, list) in join_until_size_limit(&sub_list).into_iter().enumerate() {
let subcriptions_cookie = if subscriptions_number == 0 {
"subscriptions".to_string()
} else {
format!("subscriptions{}", subscriptions_number)
};

response.insert_cookie(
Cookie::build((subcriptions_cookie, list))
.path("/")
.http_only(true)
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
.into(),
);

subscriptions_number_to_delete_from += 1;
}

// While subscriptionsNUMBER= is in the string of cookies add a response removing that cookie
while cookies_string.contains(&format!("subscriptions{subscriptions_number_to_delete_from}=")) {
// Remove that subscriptions cookie
response.remove_cookie(format!("subscriptions{subscriptions_number_to_delete_from}"));

// Increment subscriptions cookie number
subscriptions_number_to_delete_from += 1;
}
} else {
// Remove unnumbered subscriptions cookie
response.remove_cookie("subscriptions".to_string());

// Starts at one to deal with the first numbered subscription cookie and onwards
let mut subscriptions_number_to_delete_from = 1;

// While subscriptionsNUMBER= is in the string of cookies add a response removing that cookie
while cookies_string.contains(&format!("subscriptions{subscriptions_number_to_delete_from}=")) {
// Remove that subscriptions cookie
response.remove_cookie(format!("subscriptions{subscriptions_number_to_delete_from}"));

// Increment subscriptions cookie number
subscriptions_number_to_delete_from += 1;
}
}

// If there are filters to restore set them and delete any old filters cookies, otherwise delete them all
if filters.is_some() {
let filters_list: Vec<String> = filters.expect("Filters").split('+').map(str::to_string).collect();

// Start at 0 to keep track of what number we need to start deleting old subscription cookies from
let mut filters_number_to_delete_from = 0;

// Starting at 0 so we handle the subscription cookie without a number first
for (filters_number, list) in join_until_size_limit(&filters_list).into_iter().enumerate() {
let filters_cookie = if filters_number == 0 {
"filters".to_string()
} else {
format!("filters{}", filters_number)
};

response.insert_cookie(
Cookie::build((filters_cookie, list))
.path("/")
.http_only(true)
.expires(OffsetDateTime::now_utc() + Duration::weeks(52))
.into(),
);

filters_number_to_delete_from += 1;
}

// While filtersNUMBER= is in the string of cookies add a response removing that cookie
while cookies_string.contains(&format!("filters{filters_number_to_delete_from}=")) {
// Remove that filters cookie
response.remove_cookie(format!("filters{filters_number_to_delete_from}"));

// Increment filters cookie number
filters_number_to_delete_from += 1;
}
} else {
// Remove unnumbered filters cookie
response.remove_cookie("filters".to_string());

// Starts at one to deal with the first numbered subscription cookie and onwards
let mut filters_number_to_delete_from = 1;

// While filtersNUMBER= is in the string of cookies add a response removing that cookie
while cookies_string.contains(&format!("filters{filters_number_to_delete_from}=")) {
// Remove that sfilters cookie
response.remove_cookie(format!("filters{filters_number_to_delete_from}"));

// Increment filters cookie number
filters_number_to_delete_from += 1;
}
}

response
}

Expand Down
2 changes: 1 addition & 1 deletion src/subreddit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ pub fn can_access_quarantine(req: &Request<Body>, sub: &str) -> bool {
}

// Join items in chunks of 4000 bytes in length for cookies
fn join_until_size_limit<T: std::fmt::Display>(vec: &[T]) -> Vec<std::string::String> {
pub fn join_until_size_limit<T: std::fmt::Display>(vec: &[T]) -> Vec<std::string::String> {
let mut result = Vec::new();
let mut list = String::new();
let mut current_size = 0;
Expand Down

0 comments on commit 2657be2

Please sign in to comment.