11package com .fox2code .mmm .androidacy ;
22
33import android .annotation .SuppressLint ;
4+ import android .app .Activity ;
5+ import android .content .Context ;
46import android .content .Intent ;
57import android .content .SharedPreferences ;
68import android .net .Uri ;
1012
1113import androidx .annotation .NonNull ;
1214
15+ import com .fingerprintjs .android .fingerprint .Fingerprinter ;
16+ import com .fingerprintjs .android .fingerprint .FingerprinterFactory ;
17+ import com .fox2code .foxcompat .app .FoxActivity ;
18+ import com .fox2code .foxcompat .app .internal .FoxCompat ;
1319import com .fox2code .mmm .BuildConfig ;
20+ import com .fox2code .mmm .MainActivity ;
1421import com .fox2code .mmm .MainApplication ;
1522import com .fox2code .mmm .R ;
1623import com .fox2code .mmm .manager .ModuleInfo ;
1724import com .fox2code .mmm .repo .RepoData ;
1825import com .fox2code .mmm .repo .RepoManager ;
1926import com .fox2code .mmm .repo .RepoModule ;
27+ import com .fox2code .mmm .utils .RuntimeUtils ;
2028import com .fox2code .mmm .utils .io .PropUtils ;
2129import com .fox2code .mmm .utils .io .net .Http ;
2230import com .fox2code .mmm .utils .io .net .HttpException ;
2331import com .google .android .material .dialog .MaterialAlertDialogBuilder ;
24- import com .topjohnwu .superuser .Shell ;
2532
2633import org .json .JSONArray ;
2734import org .json .JSONException ;
3138import java .io .IOException ;
3239import java .net .HttpURLConnection ;
3340import java .net .URL ;
34- import java .security .MessageDigest ;
35- import java .security .NoSuchAlgorithmException ;
3641import java .util .ArrayList ;
3742import java .util .Arrays ;
3843import java .util .Iterator ;
3944import java .util .List ;
4045import java .util .Objects ;
46+ import java .util .UUID ;
47+ import java .util .concurrent .atomic .AtomicReference ;
4148
4249import okhttp3 .HttpUrl ;
4350import timber .log .Timber ;
@@ -94,59 +101,36 @@ public static String generateDeviceId() {
94101 }
95102 // Try to get the device ID from the shared preferences
96103 SharedPreferences sharedPreferences = MainApplication .getSharedPreferences ("androidacy" );
97- String deviceIdPref = sharedPreferences .getString ("device_id " , null );
104+ String deviceIdPref = sharedPreferences .getString ("device_id_v2 " , null );
98105 if (deviceIdPref != null ) {
99106 ANDROIDACY_DEVICE_ID = deviceIdPref ;
100107 return deviceIdPref ;
101108 } else {
102- // Really not that scary - just hashes some device info. We can't even get the info
103- // we originally hashed, so it's not like we can use it to track you.
104- String deviceId = null ;
105- // Get ro.serialno if it exists
106- // First, we need to get an su shell
107- Shell .Result result = Shell .cmd ("getprop ro.serialno" ).exec ();
108- // Check if the command was successful
109- if (result .isSuccess ()) {
110- // Get the output
111- String output = result .getOut ().get (0 );
112- // Check if the output is valid
113- if (output != null && !output .isEmpty ()) {
114- deviceId = output ;
109+ Fingerprinter fp = FingerprinterFactory .create (MainApplication .getINSTANCE ().getApplicationContext ());
110+ fp .getFingerprint (Fingerprinter .Version .V_5 , fingerprint -> {
111+ ANDROIDACY_DEVICE_ID = fingerprint ;
112+ // use fingerprint
113+ // Save the device ID to the shared preferences
114+ SharedPreferences .Editor editor = sharedPreferences .edit ();
115+ editor .putString ("device_id_v2" , ANDROIDACY_DEVICE_ID );
116+ editor .apply ();
117+ return null ;
118+ });
119+ // wait for up to 5 seconds for the fingerprint to be generated (ANDROIDACY_DEVICE_ID to be set)
120+ long startTime = System .currentTimeMillis ();
121+ while (ANDROIDACY_DEVICE_ID == null && System .currentTimeMillis () - startTime < 5000 ) {
122+ try {
123+ //noinspection BusyWait
124+ Thread .sleep (100 );
125+ } catch (InterruptedException ignored ) {
126+ Thread .currentThread ().interrupt ();
115127 }
116128 }
117- // Now, get device model, manufacturer, and Android version originally from
118- String deviceModel = android .os .Build .MODEL ;
119- String deviceManufacturer = android .os .Build .MANUFACTURER ;
120- String androidVersion = android .os .Build .VERSION .RELEASE ;
121- // Append it all together
122- deviceId += deviceModel + deviceManufacturer + androidVersion ;
123- // Hash it
124- MessageDigest digest ;
125- try {
126- digest = MessageDigest .getInstance ("SHA-256" );
127- } catch (NoSuchAlgorithmException ignored ) {
128- // This should never happen so we can just return the original device ID
129- ANDROIDACY_DEVICE_ID = deviceId ;
130- return deviceId ;
131- }
132- byte [] hash = digest .digest (deviceId .getBytes ());
133- // Convert it to a hex string
134- StringBuilder hexString = new StringBuilder ();
135- for (byte b : hash ) {
136- String hex = Integer .toHexString (0xff & b );
137- if (hex .length () == 1 ) {
138- hexString .append ('0' );
139- }
140- hexString .append (hex );
129+ if (ANDROIDACY_DEVICE_ID == null ) {
130+ // fingerprint generation failed, use a random UUID
131+ ANDROIDACY_DEVICE_ID = UUID .randomUUID ().toString ();
141132 }
142- // Save it to shared preferences
143- SharedPreferences .Editor editor = sharedPreferences .edit ();
144- editor .putString ("device_id" , hexString .toString ());
145- editor .apply ();
146- // Set ANDROIDACY_DEVICE_ID
147- ANDROIDACY_DEVICE_ID = hexString .toString ();
148- // Return it
149- return hexString .toString ();
133+ return ANDROIDACY_DEVICE_ID ;
150134 }
151135 }
152136
@@ -155,8 +139,9 @@ public boolean isValidToken(String token) throws IOException {
155139 try {
156140 byte [] resp = Http .doHttpGet ("https://" + this .host + "/auth/me?token=" + token + "&device_id=" + deviceId + "&client_id=" + BuildConfig .ANDROIDACY_CLIENT_ID , false );
157141 // response is JSON
158- JSONObject jsonObject = new JSONObject (Arrays . toString (resp ));
142+ JSONObject jsonObject = new JSONObject (new String (resp ));
159143 memberLevel = jsonObject .getString ("role" );
144+ Timber .d ("Member level: %s" , memberLevel );
160145 JSONArray memberPermissions = jsonObject .getJSONArray ("permissions" );
161146 // set role and permissions on userInfo property
162147 userInfo = new String [][]{{"role" , memberLevel }, {"permissions" , String .valueOf (memberPermissions )}};
@@ -252,7 +237,7 @@ protected boolean prepare() {
252237 try {
253238 Timber .i ("Requesting new token..." );
254239 // POST json request to https://production-api.androidacy.com/auth/register
255- token = Arrays . toString (Http .doHttpPost ("https://" + this .host + "/auth/register?client_id=" + BuildConfig .ANDROIDACY_CLIENT_ID , "{\" device_id\" :\" " + deviceId + "\" }" , false ));
240+ token = new String (Http .doHttpPost ("https://" + this .host + "/auth/register?client_id=" + BuildConfig .ANDROIDACY_CLIENT_ID , "{\" device_id\" :\" " + deviceId + "\" }" , false ));
256241 // Parse token
257242 try {
258243 JSONObject jsonObject = new JSONObject (token );
@@ -261,6 +246,7 @@ protected boolean prepare() {
261246 //noinspection SuspiciousRegexArgument
262247 Timber .d ("Token: %s" , token .substring (0 , token .length () - 4 ).replaceAll ("." , "*" ) + token .substring (token .length () - 4 ));
263248 memberLevel = jsonObject .getString ("role" );
249+ Timber .d ("Member level: %s" , memberLevel );
264250 } catch (JSONException e ) {
265251 Timber .e (e , "Failed to parse token" );
266252 // Show a toast
0 commit comments