rework cookies and improve cust repos

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/27/head
androidacy-user 3 years ago
parent 252a44f7e0
commit 68a4c54ef8

@ -35,6 +35,10 @@ public final class CustomRepoData extends RepoData {
JSONObject jsonObject = new JSONObject( JSONObject jsonObject = new JSONObject(
new String(Http.doHttpGet(this.getUrl(), new String(Http.doHttpGet(this.getUrl(),
false), StandardCharsets.UTF_8)); false), StandardCharsets.UTF_8));
// make sure there's at least a name and a modules or data object
if (!jsonObject.has("name") || (!jsonObject.has("modules") && !jsonObject.has("data"))) {
throw new IllegalArgumentException("Invalid repo: " + this.getUrl());
}
this.name = jsonObject.getString("name").trim(); this.name = jsonObject.getString("name").trim();
this.website = jsonObject.optString("website"); this.website = jsonObject.optString("website");
this.support = jsonObject.optString("support"); this.support = jsonObject.optString("support");

@ -71,8 +71,6 @@ import com.google.android.material.textfield.MaterialAutoCompleteTextView;
import com.mikepenz.aboutlibraries.LibsBuilder; import com.mikepenz.aboutlibraries.LibsBuilder;
import com.topjohnwu.superuser.internal.UiThreadHandler; import com.topjohnwu.superuser.internal.UiThreadHandler;
import org.json.JSONException;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -666,8 +664,11 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
public static class RepoFragment extends PreferenceFragmentCompat { public static class RepoFragment extends PreferenceFragmentCompat {
private static final int CUSTOM_REPO_ENTRIES = 5; private static final int CUSTOM_REPO_ENTRIES = 5;
// *says proudly* I stole it /**
// namely, from https://github.com/NeoApplications/Neo-Wellbeing/blob/9fca4136263780c022f9ec6433c0b43d159166db/app/src/main/java/org/eu/droid_ng/wellbeing/prefs/SettingsActivity.java#L101 * <i>proudly</i> I stole it
* <p>
* namely, from <a href="https://github.com/NeoApplications/Neo-Wellbeing/blob/9fca4136263780c022f9ec6433c0b43d159166db/app/src/main/java/org/eu/droid_ng/wellbeing/prefs/SettingsActivity.java#L101">neo wellbeing</a>
*/
public static void applyMaterial3(Preference p) { public static void applyMaterial3(Preference p) {
if (p instanceof PreferenceGroup) { if (p instanceof PreferenceGroup) {
PreferenceGroup pg = (PreferenceGroup) p; PreferenceGroup pg = (PreferenceGroup) p;
@ -816,6 +817,8 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
// Get the dummy pref_androidacy_repo_api_token preference with id pref_androidacy_repo_api_token // Get the dummy pref_androidacy_repo_api_token preference with id pref_androidacy_repo_api_token
// we have to use the id because the key is different // we have to use the id because the key is different
EditTextPreference prefAndroidacyRepoApiKey = Objects.requireNonNull(findPreference("pref_androidacy_repo_api_token")); EditTextPreference prefAndroidacyRepoApiKey = Objects.requireNonNull(findPreference("pref_androidacy_repo_api_token"));
// add validation to the EditTextPreference
// string must be 64 characters long, and only allows alphanumeric characters
prefAndroidacyRepoApiKey.setTitle(R.string.api_key); prefAndroidacyRepoApiKey.setTitle(R.string.api_key);
prefAndroidacyRepoApiKey.setSummary(R.string.api_key_summary); prefAndroidacyRepoApiKey.setSummary(R.string.api_key_summary);
prefAndroidacyRepoApiKey.setDialogTitle(R.string.api_key); prefAndroidacyRepoApiKey.setDialogTitle(R.string.api_key);
@ -834,6 +837,14 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
}); });
prefAndroidacyRepoApiKey.setPositiveButtonText(R.string.save_api_key); prefAndroidacyRepoApiKey.setPositiveButtonText(R.string.save_api_key);
prefAndroidacyRepoApiKey.setOnPreferenceChangeListener((preference, newValue) -> { prefAndroidacyRepoApiKey.setOnPreferenceChangeListener((preference, newValue) -> {
// validate the api key client side first. should be 64 characters long, and only allow alphanumeric characters
if (!newValue.toString().matches("[a-zA-Z0-9]{64}")) {
// Show snack bar with error
Snackbar.make(requireView(), R.string.api_key_mismatch, Snackbar.LENGTH_LONG).show();
// Restore the original api key
prefAndroidacyRepoApiKey.setText(originalApiKeyRef[0]);
return false;
}
// Make sure originalApiKeyRef is not null // Make sure originalApiKeyRef is not null
if (originalApiKeyRef[0].equals(newValue)) if (originalApiKeyRef[0].equals(newValue))
return true; return true;
@ -990,13 +1001,18 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
public void run() { public void run() {
try { try {
customRepoData.quickPrePopulate(); customRepoData.quickPrePopulate();
UiThreadHandler.handler.post(() -> updateCustomRepoList(false));
} catch ( } catch (
IOException | Exception e) {
JSONException |
NoSuchAlgorithmException e) {
Timber.e(e); Timber.e(e);
// show new dialog
new Handler(Looper.getMainLooper()).post(() -> new MaterialAlertDialogBuilder(context)
.setTitle(R.string.error_adding)
.setMessage(e.getMessage())
.setPositiveButton(android.R.string.ok, (dialog1, which1) -> {
})
.show());
} }
UiThreadHandler.handler.post(() -> updateCustomRepoList(false));
} }
}.start(); }.start();
} }

@ -8,6 +8,7 @@ import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.MainApplication; import com.fox2code.mmm.MainApplication;
import java.io.IOException; import java.io.IOException;
@ -16,6 +17,7 @@ import java.util.HashSet;
import okhttp3.Interceptor; import okhttp3.Interceptor;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import timber.log.Timber;
/** /**
* This interceptor put all the Cookies in Preferences in the Request. * This interceptor put all the Cookies in Preferences in the Request.
@ -42,14 +44,20 @@ public class AddCookiesInterceptor implements Interceptor {
// Some APIs die if you do it differently. // Some APIs die if you do it differently.
StringBuilder cookiestring = new StringBuilder(); StringBuilder cookiestring = new StringBuilder();
for (String cookie : preferences) { for (String cookie : preferences) {
String[] parser = cookie.split(";"); // if cookie doesn't end in a semicolon, add one.
cookiestring.append(parser[0]).append("; "); if (!cookie.endsWith(";")) {
cookie = cookie + ";";
}
cookiestring.append(cookie).append(" ");
} }
builder.addHeader("Cookie", cookiestring.toString()); // if ccokiestring doesn't have is_foxmmm cookie, add a never expiring one for the current domain.
if (!cookiestring.toString().contains("is_foxmmm")) {
for (String cookie : preferences) { cookiestring.append("is_foxmmm=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/; domain=").append(chain.request().url().host()).append("; SameSite=None; Secure;");
builder.addHeader("Cookie", cookie);
} }
if (BuildConfig.DEBUG_HTTP) {
Timber.d("Sending cookies: %s", cookiestring.toString());
}
builder.addHeader("Cookie", cookiestring.toString());
return chain.proceed(builder.build()); return chain.proceed(builder.build());
} }

@ -234,7 +234,13 @@ public class Http {
// Log, but set all query parameters values to "****" while keeping the keys // Log, but set all query parameters values to "****" while keeping the keys
Timber.d("doHttpGet: %s", url.replaceAll("=[^&]*", "=****")); Timber.d("doHttpGet: %s", url.replaceAll("=[^&]*", "=****"));
} }
Response response = (allowCache ? getHttpClientWithCache() : getHttpClient()).newCall(new Request.Builder().url(url).get().build()).execute(); Response response;
try {
response = (allowCache ? getHttpClientWithCache() : getHttpClient()).newCall(new Request.Builder().url(url).get().build()).execute();
} catch (IOException e) {
Timber.e(e, "Failed to fetch %s", url.replaceAll("=[^&]*", "=****"));
throw new HttpException(e.getMessage(), 0);
}
if (BuildConfig.DEBUG_HTTP) { if (BuildConfig.DEBUG_HTTP) {
Timber.d("doHttpGet: request executed"); Timber.d("doHttpGet: request executed");
} }

@ -10,6 +10,7 @@ import android.content.SharedPreferences;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.MainApplication; import com.fox2code.mmm.MainApplication;
import java.io.IOException; import java.io.IOException;
@ -17,6 +18,7 @@ import java.util.HashSet;
import okhttp3.Interceptor; import okhttp3.Interceptor;
import okhttp3.Response; import okhttp3.Response;
import timber.log.Timber;
public class ReceivedCookiesInterceptor implements Interceptor { public class ReceivedCookiesInterceptor implements Interceptor {
private final Context context; private final Context context;
@ -33,8 +35,14 @@ public class ReceivedCookiesInterceptor implements Interceptor {
HashSet<String> cookies = (HashSet<String>) MainApplication.getSharedPreferences().getStringSet("PREF_COOKIES", new HashSet<>()); HashSet<String> cookies = (HashSet<String>) MainApplication.getSharedPreferences().getStringSet("PREF_COOKIES", new HashSet<>());
cookies.addAll(originalResponse.headers("Set-Cookie")); cookies.addAll(originalResponse.headers("Set-Cookie"));
if (!cookies.toString().contains("is_foxmmm")) {
cookies.add("is_foxmmm=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/; domain=" + chain.request().url().host() + "; SameSite=None; Secure;");
}
SharedPreferences.Editor memes = MainApplication.getSharedPreferences().edit(); SharedPreferences.Editor memes = MainApplication.getSharedPreferences().edit();
if (BuildConfig.DEBUG_HTTP) {
Timber.d("Received cookies: %s", cookies);
}
memes.putStringSet("PREF_COOKIES", cookies).apply(); memes.putStringSet("PREF_COOKIES", cookies).apply();
memes.commit(); memes.commit();
} }

@ -316,5 +316,5 @@
<string name="reset_app">Reset the app</string> <string name="reset_app">Reset the app</string>
<string name="upgraded_summary">You\'re pretty awesome! Looks like you\'ve already upgraded your subscription and are supporting Androidacy.</string> <string name="upgraded_summary">You\'re pretty awesome! Looks like you\'ve already upgraded your subscription and are supporting Androidacy.</string>
<string name="upgraded">Premium active</string> <string name="upgraded">Premium active</string>
<string name="reset_warning">If you keep seeing this screen, resetting the app might help. This will clear app data but will not effect installed modules.</string><string name="reset_app_message">This will completely remove all app data and close the app. Modules will not be uninstalled.</string><string name="reset">Reset</string><string name="reset_app_confirmation">This is going to completely wipe app data, but will not effect modules.</string> <string name="reset_warning">If you keep seeing this screen, resetting the app might help. This will clear app data but will not effect installed modules.</string><string name="reset_app_message">This will completely remove all app data and close the app. Modules will not be uninstalled.</string><string name="reset">Reset</string><string name="reset_app_confirmation">This is going to completely wipe app data, but will not effect modules.</string><string name="error_adding">Failed to add custom repo</string><string name="api_key_mismatch">API key is in an invalid format</string>
</resources> </resources>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory <PreferenceCategory
app:key="pref_androidacy_repo" app:key="pref_androidacy_repo"
app:title="@string/androidacy_repo_name"> app:title="@string/androidacy_repo_name">
@ -13,6 +13,7 @@
<EditTextPreference <EditTextPreference
app:icon="@drawable/ic_baseline_vpn_key_24" app:icon="@drawable/ic_baseline_vpn_key_24"
app:key="pref_androidacy_repo_api_token" app:key="pref_androidacy_repo_api_token"
android:maxLength="64"
app:singleLineTitle="false" app:singleLineTitle="false"
app:dependency="pref_androidacy_repo_enabled" app:dependency="pref_androidacy_repo_enabled"
app:isPreferenceVisible="false" app:isPreferenceVisible="false"

Loading…
Cancel
Save