Version 1.3.8
This commit is contained in:
		| @@ -9,8 +9,8 @@ android { | |||||||
|         applicationId "nl.privacydragon.bookwyrm" |         applicationId "nl.privacydragon.bookwyrm" | ||||||
|         minSdk 23 |         minSdk 23 | ||||||
|         targetSdk 34 |         targetSdk 34 | ||||||
|         versionCode 14 |         versionCode 15 | ||||||
|         versionName "1.3.7" |         versionName "1.3.8" | ||||||
|  |  | ||||||
|         testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' |         testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' | ||||||
|     } |     } | ||||||
| @@ -43,5 +43,7 @@ dependencies { | |||||||
|     androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' |     androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' | ||||||
|     implementation 'com.google.zxing:core:3.5.3' |     implementation 'com.google.zxing:core:3.5.3' | ||||||
|     implementation 'com.journeyapps:zxing-android-embedded:4.3.0@aar' |     implementation 'com.journeyapps:zxing-android-embedded:4.3.0@aar' | ||||||
|  |     implementation 'org.conscrypt:conscrypt-android:2.5.2' | ||||||
|  |     implementation 'com.squareup.okhttp3:okhttp:4.12.0' | ||||||
|  |  | ||||||
| } | } | ||||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								app/release/Bookwyrm-v1.3.8.apk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/release/Bookwyrm-v1.3.8.apk
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -11,8 +11,8 @@ | |||||||
|       "type": "SINGLE", |       "type": "SINGLE", | ||||||
|       "filters": [], |       "filters": [], | ||||||
|       "attributes": [], |       "attributes": [], | ||||||
|       "versionCode": 14, |       "versionCode": 15, | ||||||
|       "versionName": "1.3.7", |       "versionName": "1.3.8", | ||||||
|       "outputFile": "app-release.apk" |       "outputFile": "app-release.apk" | ||||||
|     } |     } | ||||||
|   ], |   ], | ||||||
|   | |||||||
| @@ -10,11 +10,11 @@ import android.content.SharedPreferences; | |||||||
| import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||||
| import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||||
| import android.net.Uri; | import android.net.Uri; | ||||||
| import android.os.Build; |  | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
| import android.util.Base64; | import android.util.Base64; | ||||||
| import android.view.KeyEvent; | import android.view.KeyEvent; | ||||||
| import android.view.View; | import android.view.View; | ||||||
|  | import android.webkit.CookieManager; | ||||||
| import android.webkit.JavascriptInterface; | import android.webkit.JavascriptInterface; | ||||||
| import android.webkit.ValueCallback; | import android.webkit.ValueCallback; | ||||||
| import android.webkit.WebChromeClient; | import android.webkit.WebChromeClient; | ||||||
| @@ -33,17 +33,10 @@ import androidx.core.content.ContextCompat; | |||||||
| import com.journeyapps.barcodescanner.ScanContract; | import com.journeyapps.barcodescanner.ScanContract; | ||||||
| import com.journeyapps.barcodescanner.ScanOptions; | import com.journeyapps.barcodescanner.ScanOptions; | ||||||
|  |  | ||||||
| import java.io.BufferedInputStream; | import org.conscrypt.Conscrypt; | ||||||
|  |  | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; |  | ||||||
| import java.io.UnsupportedEncodingException; | import java.io.UnsupportedEncodingException; | ||||||
| import java.net.CookieHandler; |  | ||||||
| import java.net.CookieManager; |  | ||||||
| import java.net.CookieStore; |  | ||||||
| import java.net.HttpCookie; |  | ||||||
| import java.net.HttpURLConnection; |  | ||||||
| import java.net.URI; |  | ||||||
| import java.net.URL; |  | ||||||
| import java.net.URLEncoder; | import java.net.URLEncoder; | ||||||
| import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||||
| import java.security.InvalidAlgorithmParameterException; | import java.security.InvalidAlgorithmParameterException; | ||||||
| @@ -52,10 +45,9 @@ import java.security.Key; | |||||||
| import java.security.KeyStore; | import java.security.KeyStore; | ||||||
| import java.security.KeyStoreException; | import java.security.KeyStoreException; | ||||||
| import java.security.NoSuchAlgorithmException; | import java.security.NoSuchAlgorithmException; | ||||||
|  | import java.security.Security; | ||||||
| import java.security.UnrecoverableKeyException; | import java.security.UnrecoverableKeyException; | ||||||
| import java.security.cert.CertificateException; | import java.security.cert.CertificateException; | ||||||
| import java.util.List; |  | ||||||
| import java.util.Objects; |  | ||||||
|  |  | ||||||
| import javax.crypto.BadPaddingException; | import javax.crypto.BadPaddingException; | ||||||
| import javax.crypto.Cipher; | import javax.crypto.Cipher; | ||||||
| @@ -63,10 +55,20 @@ import javax.crypto.IllegalBlockSizeException; | |||||||
| import javax.crypto.NoSuchPaddingException; | import javax.crypto.NoSuchPaddingException; | ||||||
| import javax.crypto.spec.GCMParameterSpec; | import javax.crypto.spec.GCMParameterSpec; | ||||||
|  |  | ||||||
|  | import okhttp3.FormBody; | ||||||
|  | import okhttp3.Headers; | ||||||
|  | import okhttp3.Interceptor; | ||||||
|  | import okhttp3.OkHttpClient; | ||||||
|  | import okhttp3.Request; | ||||||
|  | import okhttp3.RequestBody; | ||||||
|  | import okhttp3.Response; | ||||||
|  |  | ||||||
| public class StartActivity extends AppCompatActivity { | public class StartActivity extends AppCompatActivity { | ||||||
|     WebView myWebView; |     WebView myWebView; | ||||||
|     ProgressBar LoadIndicator; |     ProgressBar LoadIndicator; | ||||||
|     public ValueCallback<Uri[]> omhooglader; |     public ValueCallback<Uri[]> omhooglader; | ||||||
|  |     String putje = ""; | ||||||
|  |     String sessie = ""; | ||||||
|     @SuppressLint("SetJavaScriptEnabled") |     @SuppressLint("SetJavaScriptEnabled") | ||||||
|     @Override |     @Override | ||||||
|     protected void onCreate(Bundle savedInstanceState) { |     protected void onCreate(Bundle savedInstanceState) { | ||||||
| @@ -89,6 +91,7 @@ public class StartActivity extends AppCompatActivity { | |||||||
|                 }); |                 }); | ||||||
|         myWebView = (WebView) findViewById(R.id.webview); |         myWebView = (WebView) findViewById(R.id.webview); | ||||||
|         myWebView.setVisibility(View.GONE); |         myWebView.setVisibility(View.GONE); | ||||||
|  |         myWebView.getSettings().setUserAgentString(getString(R.string.gebruikersagent)); | ||||||
|         myWebView.getSettings().setJavaScriptEnabled(true); |         myWebView.getSettings().setJavaScriptEnabled(true); | ||||||
|         myWebView.addJavascriptInterface(new Object() |         myWebView.addJavascriptInterface(new Object() | ||||||
|         { |         { | ||||||
| @@ -236,11 +239,32 @@ public class StartActivity extends AppCompatActivity { | |||||||
| //          LoadIndicator.setVisibility(View.VISIBLE); | //          LoadIndicator.setVisibility(View.VISIBLE); | ||||||
| //          android.webkit.CookieManager oven = android.webkit.CookieManager.getInstance(); | //          android.webkit.CookieManager oven = android.webkit.CookieManager.getInstance(); | ||||||
|           //myWebView.loadUrl("javascript:this.document.location.href = 'source://' + encodeURI(document.documentElement.outerHTML);"); |           //myWebView.loadUrl("javascript:this.document.location.href = 'source://' + encodeURI(document.documentElement.outerHTML);"); | ||||||
|  |         //try { | ||||||
|  |             //See if we are already logged in. | ||||||
|  |             CookieManager oven = CookieManager.getInstance(); | ||||||
|  |             String koek = oven.getCookie("https://" + server); | ||||||
|  |             if (koek != null) { | ||||||
|  |                 if (koek.indexOf("sessionid") != -1) { | ||||||
|  |                     myWebView.loadUrl("https://" + server); | ||||||
|  |                 } else { | ||||||
|  |                     //This should get the login page, retreive the csrf-middlewaretoken, and then log the user in using a POST-request. | ||||||
|                     try { |                     try { | ||||||
|             getMiddleWareTokenAndLogIn(server, name, passw); //This should get the login page, retreive the csrf-middlewaretoken, and then log the user in using a POST-request. |                         getMiddleWareTokenAndLogIn(server, name, passw); | ||||||
|                     } catch (IOException e) { |                     } catch (IOException e) { | ||||||
|                         throw new RuntimeException(e); |                         throw new RuntimeException(e); | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 //This should get the login page, retreive the csrf-middlewaretoken, and then log the user in using a POST-request. | ||||||
|  |                 try { | ||||||
|  |                     getMiddleWareTokenAndLogIn(server, name, passw); | ||||||
|  |                 } catch (IOException e) { | ||||||
|  |                     throw new RuntimeException(e); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         //} catch (IOException e) { | ||||||
|  |         //    throw new RuntimeException(e); | ||||||
|  |         //} | ||||||
|  |  | ||||||
|  |  | ||||||
|     } |     } | ||||||
| @@ -254,79 +278,115 @@ public class StartActivity extends AppCompatActivity { | |||||||
|             public void run() { |             public void run() { | ||||||
|                 try { |                 try { | ||||||
|                     //Load the login page, and do not forget to take some cookies. |                     //Load the login page, and do not forget to take some cookies. | ||||||
|                     URL url = new URL("https://" + server + "/login"); |                     Security.insertProviderAt(Conscrypt.newProvider(), 1); | ||||||
|                     CookieManager koekManager = new CookieManager(); |                     //URL url = new URL("https://" + server + "/"); | ||||||
|                     CookieHandler.setDefault(koekManager); |                     String speculaas = ""; | ||||||
|                     CookieStore bakker = koekManager.getCookieStore(); |                     String speculaasBeslag = ""; | ||||||
|                     HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); |                     //The login page loading is done using OkHttpClient. | ||||||
|                     try { |                     OkHttpClient client = new OkHttpClient(); | ||||||
|                         //Get the input stream, and move it all into a byte array. |                     Request aanvraag = new Request.Builder() | ||||||
|                         InputStream ina = new BufferedInputStream(urlConnection.getInputStream()); |                             .url("https://" + server + "/") | ||||||
|                         byte[] pagina = null; |                             .header("User-Agent", getString(R.string.gebruikersagent)) | ||||||
|                         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { |                             .build(); | ||||||
|                             pagina = ina.readAllBytes(); |                     //Get an answer! | ||||||
|                         } else { |                     try (Response antwoord = client.newCall(aanvraag).execute()) { | ||||||
|                             //I truly hope that this byte array will always be big enough... |                         if (!antwoord.isSuccessful()) throw new IOException("Unexpected code " + antwoord); | ||||||
|                             //The Tiramisu+ way is much better... |                         //Search the headers for the 'set-cookie' header so we can eat a cookie! | ||||||
|                             pagina = new byte[30000]; |                         Headers cenna = antwoord.headers(); | ||||||
|                             ina.read(pagina); |                         for (int i = 0; i < cenna.size(); i++) { | ||||||
|  |                             if (cenna.name(i).equals("set-cookie")) { | ||||||
|  |                                 speculaas = cenna.value(i); | ||||||
|  |                                 speculaasBeslag = speculaas.split(";")[0]; | ||||||
|                             } |                             } | ||||||
|                         try { |  | ||||||
|                             ina.close(); |  | ||||||
|                         } catch (IOException e) { |  | ||||||
|                             throw new RuntimeException(e); |  | ||||||
|                         } |                         } | ||||||
|                         //And now create a string out of the byte array, so we can retreive the middleware token. |                         //And then get the HTML body. | ||||||
|                         String zooi = new String(pagina); |                         assert antwoord.body() != null; | ||||||
|  |                         String zooi = antwoord.body().string(); | ||||||
|  | //                    CookieManager koekManager = new CookieManager(); | ||||||
|  | //                    CookieHandler.setDefault(koekManager); | ||||||
|  | //                    CookieStore bakker = koekManager.getCookieStore(); | ||||||
|  | //                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); | ||||||
|  | //                    try { | ||||||
|  | //                        InputStream ina = new BufferedInputStream(urlConnection.getInputStream()); | ||||||
|  | //                        byte[] pagina = null; | ||||||
|  | //                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | ||||||
|  | //                            pagina = ina.readAllBytes(); | ||||||
|  | //                        } else { | ||||||
|  | //                            //I truly hope that this byte array will always be big enough... | ||||||
|  | //                            //The Tiramisu+ way is much better... | ||||||
|  | //                            pagina = new byte[30000]; | ||||||
|  | //                            ina.read(pagina); | ||||||
|  | //                        } | ||||||
|  | //                        try { | ||||||
|  | //                            ina.close(); | ||||||
|  | //                        } catch (IOException e) { | ||||||
|  | //                            throw new RuntimeException(e); | ||||||
|  | //                        } | ||||||
|  | //                        //We should not forget closing the connection we used for hearing what csrf cookie and token we needed. | ||||||
|  | //                        urlConnection.disconnect(); | ||||||
|  | //                        //And now create a string out of the byte array, so we can retreive the middleware token. | ||||||
|  | //                        String zooi = new String(pagina); | ||||||
|                         //Very easy to get the token by taking the text that it is preceded by in the raw html as the regex for a split() function! |                         //Very easy to get the token by taking the text that it is preceded by in the raw html as the regex for a split() function! | ||||||
|                         String[] opgebroken = zooi.split("name=\"csrfmiddlewaretoken\" value=\""); |                         String[] opgebroken = zooi.split("name=\"csrfmiddlewaretoken\" value=\""); | ||||||
|                         //For that gives as second element the token, followed by all the following html code. Then strip that code off, using the immediately following characters as regex. |                         //For that gives as second element the token, followed by all the following html code. Then strip that code off, using the immediately following characters as regex. | ||||||
|                         String[] breukjes = opgebroken[1].split("\">"); |                         String[] breukjes = opgebroken[1].split("\">"); | ||||||
|                         //Of course, the token is then the first element in our array. |                         //Of course, the token is then the first element in our array. | ||||||
|                         String token = breukjes[0]; |                         String token = breukjes[0]; | ||||||
|  |                         //Log.d("botbreuk", token); | ||||||
|                         String gegevens = null; |                         String gegevens = null; | ||||||
|                         //Initiate some strings to use for the delicious csrf cookie. |                         //Initiate some strings to use for the delicious csrf cookie. | ||||||
|                         String speculaas = "", THT = ""; |                         //String speculaas = "", THT = ""; | ||||||
|                         //How to get the cookies? First get the cookie collection, the cookie box so to say, and then... | //                        //How to get the cookies? First get the cookie collection, the cookie box so to say, and then... | ||||||
|                         List<HttpCookie> koektrommel = bakker.get(URI.create("https://" + server)); | //                        List<HttpCookie> koektrommel = bakker.get(URI.create("https://" + server)); | ||||||
|                         //Log.d("koek", koektrommel.toString()); | //                        Log.d("koek", koektrommel.toString()); | ||||||
|                         //... for every cookie in it check to see if it is the csrftoken named cookie. | //                        //... for every cookie in it check to see if it is the csrftoken named cookie. | ||||||
|                         for (int i = 0; i < koektrommel.size(); ++i) { | //                        for (int i = 0; i < koektrommel.size(); ++i) { | ||||||
|                             HttpCookie koekje = koektrommel.get(i); | //                            HttpCookie koekje = koektrommel.get(i); | ||||||
|                             if (Objects.equals(koekje.getName(), "csrftoken")) { | //                            if (Objects.equals(koekje.getName(), "csrftoken")) { | ||||||
|                                 //If it is the csrftoken cookie, get the value of it, and the expiration date of it. | //                                //If it is the csrftoken cookie, get the value of it, and the expiration date of it. | ||||||
|                                 speculaas = koekje.toString(); | //                                speculaas = koekje.toString(); | ||||||
|                                 THT = String.valueOf(koekje.getMaxAge()); | //                                THT = String.valueOf(koekje.getMaxAge()); | ||||||
|                                 //Log.d("domein", koekje.getDomain()); | //                                //Log.d("domein", koekje.getDomain()); | ||||||
|                             } | //                            } | ||||||
|                         } | //                        } | ||||||
|                         //And then set the data string up for use in the POST request, with the csrf middleware token, the username, and the password. |                         //And then set the data string up for use in the POST request, with the csrf middleware token, the username, and the password. | ||||||
|                         try { |                         try { | ||||||
|                             gegevens = "csrfmiddlewaretoken=" + URLEncoder.encode(token, "UTF-8") + "&localname=" + URLEncoder.encode(name, "UTF-8") + "&password=" + URLEncoder.encode(passw, "UTF-8"); |                             gegevens = "csrfmiddlewaretoken=" + URLEncoder.encode(token, "UTF-8") + "&localname=" + URLEncoder.encode(name, "UTF-8") + "&password=" + URLEncoder.encode(passw, "UTF-8"); | ||||||
|                         } catch (UnsupportedEncodingException e) { |                         } catch (UnsupportedEncodingException e) { | ||||||
|                             throw new RuntimeException(e); |                             throw new RuntimeException(e); | ||||||
|                         } |                         } | ||||||
|  |                         RequestBody keurslijf = new FormBody.Builder() | ||||||
|  |                                 .add("csrfmiddlewaretoken", token) | ||||||
|  |                                 .add("localname", name) | ||||||
|  |                                 .add("password", passw) | ||||||
|  |                                 .build(); | ||||||
|  |  | ||||||
|                         String finalGegevens = gegevens; |                         String finalGegevens = gegevens; | ||||||
|                         //Log.d("token", speculaas); |                         //Log.d("gegevens", finalGegevens); | ||||||
|  |                         //Log.d("beslag", speculaasBeslag); | ||||||
|                         String finalSpeculaas = speculaas; |                         String finalSpeculaas = speculaas; | ||||||
|                         String finalTHT = THT; |                         //String finalTHT = THT; | ||||||
|  |                         logInAndGetHTML(server, keurslijf, speculaasBeslag); | ||||||
|                         //Then we have to run a bit of code on the main (UI) thread. To be able to work with the webview... |                         //Then we have to run a bit of code on the main (UI) thread. To be able to work with the webview... | ||||||
|                         runOnUiThread(new Runnable() { |                         runOnUiThread(new Runnable() { | ||||||
|                             @Override |                             @Override | ||||||
|                             public void run() { |                             public void run() { | ||||||
|                                 //First we have to get the cookie manager of the webview, so we can hand it the csrf cookie. |                                 //First we have to get the cookie manager of the webview, so we can hand it the csrf cookie. | ||||||
|                                 //Without being fed the correct csrf cookie, the Wyrm will refuse our request. The wyrm is a very picky eater! |                                 //Without being fed the correct csrf cookie, the Wyrm will refuse our request. The wyrm is a very picky eater! | ||||||
|                                               android.webkit.CookieManager oven = android.webkit.CookieManager.getInstance(); |                                 CookieManager oven = CookieManager.getInstance(); | ||||||
|                                 //Bake the cookie into the webview. |                                 //Bake the cookie into the webview. | ||||||
|                                               oven.setCookie("https://" + server, finalSpeculaas + "; Max-Age=" + finalTHT + "; Path=/; SameSite=Lax; Secure"); |                                 oven.setCookie("https://" + server, finalSpeculaas); | ||||||
|  |                                 //And bake the session cookie as well. | ||||||
|  |                                 oven.setCookie("https://" + server, sessie); | ||||||
|                                 //And then finally it is time to send a POST request from the webview to log in. |                                 //And then finally it is time to send a POST request from the webview to log in. | ||||||
|                                               myWebView.postUrl("https://" + server + "/login?next=/", finalGegevens.getBytes()); |                                 //myWebView.postUrl("https://" + server + "/login?next=/", finalGegevens.getBytes()); | ||||||
|  |                                 myWebView.loadDataWithBaseURL("https://" + server, putje, null, null, "https://" + server + "/login"); | ||||||
|                             } |                             } | ||||||
|                         }); |                         }); | ||||||
|  |  | ||||||
|                     } finally { |                     } finally { | ||||||
|                         //We should not forget closing the connection we used for hearing what csrf cookie and token we needed. | //                        //We should not forget closing the connection we used for hearing what csrf cookie and token we needed. | ||||||
|                         urlConnection.disconnect(); | //                        urlConnection.disconnect(); | ||||||
|                     } |                     } | ||||||
|                 } catch (Exception e) { |                 } catch (Exception e) { | ||||||
|                     throw new RuntimeException(e); |                     throw new RuntimeException(e); | ||||||
| @@ -336,7 +396,75 @@ public class StartActivity extends AppCompatActivity { | |||||||
|         //^Here ends all that new Thread() code. |         //^Here ends all that new Thread() code. | ||||||
|         //⇓Run all the code in the thread. |         //⇓Run all the code in the thread. | ||||||
|         draadje.start(); |         draadje.start(); | ||||||
|         //return token; |     } | ||||||
|  |     public void logInAndGetHTML(String server, RequestBody lichaam, String speculoos) throws IOException { | ||||||
|  | //        Thread kabel = new Thread(new Runnable() { | ||||||
|  | //            @Override | ||||||
|  | //            public void run() { | ||||||
|  | //                try { | ||||||
|  | //                    //Load the login page, and do not forget to take some cookies. | ||||||
|  |         Security.insertProviderAt(Conscrypt.newProvider(), 1); | ||||||
|  |         //Create a client using CookieMonster, so we can retrieve cookies from the redirect. | ||||||
|  |         OkHttpClient client = new OkHttpClient.Builder() | ||||||
|  |                 .addNetworkInterceptor(new CookieMonster()) | ||||||
|  |                 .build(); | ||||||
|  |         //URL url = new URL("https://" + server + "/"); | ||||||
|  |         //CookieManager koekManager = new CookieManager(); | ||||||
|  |         //CookieHandler.setDefault(koekManager); | ||||||
|  |         //CookieStore bakker = koekManager.getCookieStore(); | ||||||
|  |         Request verzoek = new Request.Builder() | ||||||
|  |                 .url("https://" + server + "/login?next=/") | ||||||
|  |                 .header("User-Agent", getString(R.string.gebruikersagent)) | ||||||
|  |                 .addHeader("origin", "https://" + server) | ||||||
|  |                 .addHeader("cookie", speculoos) | ||||||
|  |                 .post(lichaam) | ||||||
|  |                 .build(); | ||||||
|  |         try (Response reactie = client.newCall(verzoek).execute()) { | ||||||
|  |             if (!reactie.isSuccessful()) | ||||||
|  |                 throw new IOException("Unexpected code " + reactie); | ||||||
|  |             assert reactie.body() != null; | ||||||
|  |             putje = reactie.body().string(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  | //                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); | ||||||
|  | //                    urlConnection.setRequestProperty("origin", "https://" + server); | ||||||
|  | //                    byte[] paarden = gegevens.getBytes(); | ||||||
|  | //                    try { | ||||||
|  | //                        urlConnection.setDoOutput(true); | ||||||
|  | //                        urlConnection.setChunkedStreamingMode(0); | ||||||
|  | // | ||||||
|  | //                        OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream()); | ||||||
|  | //                        out.write(paarden); | ||||||
|  | //                        out.flush(); | ||||||
|  | // | ||||||
|  | //                        InputStream in = new BufferedInputStream(urlConnection.getInputStream()); | ||||||
|  | //                        byte[] pagina = null; | ||||||
|  | //                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { | ||||||
|  | //                            pagina = in.readAllBytes(); | ||||||
|  | //                        } else { | ||||||
|  | //                            //I truly hope that this byte array will always be big enough... | ||||||
|  | //                            //The Tiramisu+ way is much better... | ||||||
|  | //                            pagina = new byte[30000]; | ||||||
|  | //                            in.read(pagina); | ||||||
|  | //                        } | ||||||
|  | //                        try { | ||||||
|  | //                            in.close(); | ||||||
|  | //                        } catch (IOException e) { | ||||||
|  | //                            throw new RuntimeException(e); | ||||||
|  | //                        } | ||||||
|  | //                        html[0] = new String(pagina); | ||||||
|  | //                    } finally { | ||||||
|  | //                        urlConnection.disconnect(); | ||||||
|  | //                    } | ||||||
|  |  | ||||||
|  | //                } catch (Exception e) { | ||||||
|  | //                    throw new RuntimeException(e); | ||||||
|  | //                } | ||||||
|  | //            } | ||||||
|  | //        }); | ||||||
|  | //        kabel.start(); | ||||||
|  |         //Log.d("lichaam", putje); | ||||||
|  |         //return putje; | ||||||
|     } |     } | ||||||
|     private final ActivityResultLauncher<ScanOptions> barcodeLanceerder = registerForActivityResult(new ScanContract(), |     private final ActivityResultLauncher<ScanOptions> barcodeLanceerder = registerForActivityResult(new ScanContract(), | ||||||
|             result -> { |             result -> { | ||||||
| @@ -394,6 +522,33 @@ public class StartActivity extends AppCompatActivity { | |||||||
|         } |         } | ||||||
|         return super.onKeyLongPress(keyCode, event); |         return super.onKeyLongPress(keyCode, event); | ||||||
|     } |     } | ||||||
|  |     final class CookieMonster implements Interceptor { | ||||||
|  |         @Override public Response intercept(Interceptor.Chain chain) throws IOException { | ||||||
|  |             //Om ingelogd te blijven moeten we het sessiekoekje aan kunnen bieden. | ||||||
|  |             //Die moeten we dan wel eerst uit het koekblik pakken! | ||||||
|  |             Request eersteVerzoek = chain.request(); | ||||||
|  |             //Eerst moeten we controleren of er al een sessiekoekje is. Als dat niet zo is, dan is dit het echte eerste verzoek. | ||||||
|  |             if (sessie.isEmpty()) { | ||||||
|  |                 //In dat geval halen we de reactie op om het koekje te kunnen pakken! | ||||||
|  |                 Response eersteReactie = chain.proceed(chain.request()); | ||||||
|  |                 Headers hoofden = eersteReactie.headers(); | ||||||
|  |                 for (int i = 0; i < hoofden.size(); i++) { | ||||||
|  |                     if (hoofden.name(i).equals("set-cookie") && hoofden.value(i).startsWith("session")) { | ||||||
|  |                         sessie = hoofden.value(i); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 //Nadat we het koekje hebben moet de reactie doorgebriefd worden aan de 'client', | ||||||
|  |                 //die dan het volgende verzoek zal gaan doen vanwege de 302-redirect bij het inloggen. | ||||||
|  |                 return eersteReactie; | ||||||
|  |             } | ||||||
|  |             //Het koekje is er! Hoera! | ||||||
|  |             //Het nieuwe verzoek moet wel met het sessiekoekje verzonden worden, anders zijn we alsnog niet ingelogd! | ||||||
|  |             Request nieuwVerzoek = eersteVerzoek.newBuilder() | ||||||
|  |                     .addHeader("cookie", sessie) | ||||||
|  |                     .build(); | ||||||
|  |             return chain.proceed(nieuwVerzoek); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|     //Here is code to make sure that links of the bookwyrm server are handled within the webview client, instead of having it open in the default browser. |     //Here is code to make sure that links of the bookwyrm server are handled within the webview client, instead of having it open in the default browser. | ||||||
|     //Yes, I used the web for this too. |     //Yes, I used the web for this too. | ||||||
|     private class MyWebViewClient extends WebViewClient { |     private class MyWebViewClient extends WebViewClient { | ||||||
| @@ -415,6 +570,8 @@ public class StartActivity extends AppCompatActivity { | |||||||
|         @Override |         @Override | ||||||
|         public void onPageStarted(WebView view, String url, Bitmap favicon) { |         public void onPageStarted(WebView view, String url, Bitmap favicon) { | ||||||
|             LoadIndicator.setVisibility(View.VISIBLE); |             LoadIndicator.setVisibility(View.VISIBLE); | ||||||
|  |             //CookieManager oven = CookieManager.getInstance(); | ||||||
|  |             //Log.d("oven", oven.getCookie(url)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -4,4 +4,5 @@ | |||||||
|     <string name="name">blup</string> |     <string name="name">blup</string> | ||||||
|     <string name="pw">gloep</string> |     <string name="pw">gloep</string> | ||||||
|     <string name="q">wheeeee</string> |     <string name="q">wheeeee</string> | ||||||
|  |     <string name="gebruikersagent">Bookwyrm Android/1.3.8</string> | ||||||
| </resources> | </resources> | ||||||
| @@ -1,7 +1,7 @@ | |||||||
| // Top-level build file where you can add configuration options common to all sub-projects/modules. | // Top-level build file where you can add configuration options common to all sub-projects/modules. | ||||||
| plugins { | plugins { | ||||||
|     id 'com.android.application' version '8.7.3' apply false |     id 'com.android.application' version '8.8.0' apply false | ||||||
|     id 'com.android.library' version '8.7.3' apply false |     id 'com.android.library' version '8.8.0' apply false | ||||||
| } | } | ||||||
|  |  | ||||||
| task clean(type: Delete) { | task clean(type: Delete) { | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								fastlane/metadata/android/en-US/changelogs/15.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								fastlane/metadata/android/en-US/changelogs/15.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | Fixing what turned out not to work for unreleased version 1.3.7: | ||||||
|  | * Significant log-in improvements, including better security. | ||||||
|  | Further changes: | ||||||
|  | * The app now uses a custom User-Agent string. | ||||||
|  | * Two new dependencies have been added: okhttp3, and conscrypt. | ||||||
							
								
								
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| #Mon Feb 14 18:09:26 CET 2022 | #Mon Feb 14 18:09:26 CET 2022 | ||||||
| distributionBase=GRADLE_USER_HOME | distributionBase=GRADLE_USER_HOME | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user