mirror of
https://github.com/M66B/FairEmail.git
synced 2024-12-26 01:36:55 +00:00
Added pro activation procedure
This commit is contained in:
parent
15a7939b79
commit
9db8915234
5 changed files with 123 additions and 5 deletions
|
@ -24,12 +24,14 @@ import android.content.BroadcastReceiver;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
|
@ -42,11 +44,14 @@ import android.widget.ListView;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -68,6 +73,7 @@ import androidx.lifecycle.Observer;
|
|||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
public class ActivityView extends ActivityBase implements FragmentManager.OnBackStackChangedListener {
|
||||
private View view;
|
||||
private DrawerLayout drawerLayout;
|
||||
private ListView drawerList;
|
||||
private ActionBarDrawerToggle drawerToggle;
|
||||
|
@ -83,12 +89,14 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
|
|||
static final String ACTION_VIEW_MESSAGE = BuildConfig.APPLICATION_ID + ".VIEW_MESSAGE";
|
||||
static final String ACTION_EDIT_FOLDER = BuildConfig.APPLICATION_ID + ".EDIT_FOLDER";
|
||||
static final String ACTION_STORE_ATTACHMENT = BuildConfig.APPLICATION_ID + ".STORE_ATTACHMENT";
|
||||
static final String ACTION_ACTIVATE_PRO = BuildConfig.APPLICATION_ID + ".ACTIVATE_PRO";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_view);
|
||||
view = LayoutInflater.from(this).inflate(R.layout.activity_view, null);
|
||||
setContentView(view);
|
||||
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setHomeButtonEnabled(true);
|
||||
|
@ -130,6 +138,9 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
|
|||
case R.string.menu_faq:
|
||||
onMenuFAQ();
|
||||
break;
|
||||
case R.string.menu_pro:
|
||||
onMenuPro();
|
||||
break;
|
||||
case R.string.menu_privacy:
|
||||
onMenuPrivacy();
|
||||
break;
|
||||
|
@ -180,6 +191,10 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
|
|||
if (getIntentFAQ().resolveActivity(getPackageManager()) != null)
|
||||
drawerArray.add(new DrawerItem(ActivityView.this, R.layout.item_drawer, R.drawable.baseline_question_answer_24, R.string.menu_faq));
|
||||
|
||||
Intent pro = getIntentPro();
|
||||
if (pro == null || pro.resolveActivity(getPackageManager()) != null)
|
||||
drawerArray.add(new DrawerItem(ActivityView.this, R.layout.item_drawer, R.drawable.baseline_monetization_on_24, R.string.menu_pro));
|
||||
|
||||
if (getIntentPrivacy().resolveActivity(getPackageManager()) != null)
|
||||
drawerArray.add(new DrawerItem(ActivityView.this, R.layout.item_drawer, R.drawable.baseline_account_box_24, R.string.menu_privacy));
|
||||
|
||||
|
@ -327,6 +342,7 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
|
|||
iff.addAction(ACTION_VIEW_MESSAGE);
|
||||
iff.addAction(ACTION_EDIT_FOLDER);
|
||||
iff.addAction(ACTION_STORE_ATTACHMENT);
|
||||
iff.addAction(ACTION_ACTIVATE_PRO);
|
||||
lbm.registerReceiver(receiver, iff);
|
||||
|
||||
if (newIntent) {
|
||||
|
@ -388,13 +404,22 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
|
|||
}
|
||||
}
|
||||
|
||||
private String getChallenge() throws NoSuchAlgorithmException {
|
||||
String android_id = Settings.System.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
return Helper.sha256(android_id);
|
||||
}
|
||||
|
||||
private String getResponse() throws NoSuchAlgorithmException {
|
||||
return Helper.sha256(BuildConfig.APPLICATION_ID + getChallenge());
|
||||
}
|
||||
|
||||
private void checkIntent(Intent intent) {
|
||||
Log.i(Helper.TAG, "View intent=" + intent + " action=" + intent.getAction());
|
||||
String action = intent.getAction();
|
||||
intent.setAction(null);
|
||||
setIntent(intent);
|
||||
|
||||
if ("unseen".equals(action)) {
|
||||
intent.setAction(null);
|
||||
setIntent(intent);
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putLong("time", new Date().getTime());
|
||||
|
||||
|
@ -438,6 +463,20 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
|
|||
return intent;
|
||||
}
|
||||
|
||||
private Intent getIntentPro() {
|
||||
if (Helper.isPlayStoreInstall(this))
|
||||
return null;
|
||||
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse("https://email.faircode.eu/pro/?challenge=" + getChallenge()));
|
||||
return intent;
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Intent getIntentOtherApps() {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse("https://play.google.com/store/apps/dev?id=8420080860664580239"));
|
||||
|
@ -478,6 +517,13 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
|
|||
startActivity(getIntentFAQ());
|
||||
}
|
||||
|
||||
private void onMenuPro() {
|
||||
if (Helper.isPlayStoreInstall(this)) {
|
||||
|
||||
} else
|
||||
startActivity(getIntentPro());
|
||||
}
|
||||
|
||||
private void onMenuPrivacy() {
|
||||
startActivity(getIntentPrivacy());
|
||||
}
|
||||
|
@ -616,6 +662,31 @@ public class ActivityView extends ActivityBase implements FragmentManager.OnBack
|
|||
create.setType(intent.getStringExtra("type"));
|
||||
create.putExtra(Intent.EXTRA_TITLE, intent.getStringExtra("name"));
|
||||
startActivityForResult(create, (int) intent.getLongExtra("id", -1));
|
||||
|
||||
} else if (ACTION_ACTIVATE_PRO.equals(intent.getAction())) {
|
||||
try {
|
||||
Uri data = intent.getParcelableExtra("uri");
|
||||
String challenge = getChallenge();
|
||||
String response = data.getQueryParameter("response");
|
||||
Log.i(Helper.TAG, "Challenge=" + challenge);
|
||||
Log.i(Helper.TAG, "Response=" + response);
|
||||
String expected = getResponse();
|
||||
if (expected.equals(response)) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ActivityView.this);
|
||||
prefs.edit().putBoolean("pro", true).apply();
|
||||
Log.i(Helper.TAG, "Response valid");
|
||||
Snackbar.make(view, R.string.title_pro_valid, Snackbar.LENGTH_LONG).show();
|
||||
} else {
|
||||
Log.i(Helper.TAG, "Response invalid");
|
||||
Snackbar.make(view, R.string.title_pro_invalid, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
intent.setData(null);
|
||||
setIntent(intent);
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
Log.e(Helper.TAG, Log.getStackTraceString(ex));
|
||||
Toast.makeText(ActivityView.this, ex.getMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -82,6 +82,7 @@ import androidx.constraintlayout.widget.Group;
|
|||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
|
@ -187,8 +188,15 @@ public class FragmentMessage extends FragmentEx {
|
|||
URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
|
||||
if (link.length != 0) {
|
||||
String url = link[0].getURL();
|
||||
Uri uri = Uri.parse(url);
|
||||
|
||||
if (prefs.getBoolean("webview", false)) {
|
||||
if (BuildConfig.APPLICATION_ID.equals(uri.getHost()) && "/activate/".equals(uri.getPath())) {
|
||||
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getContext());
|
||||
lbm.sendBroadcast(
|
||||
new Intent(ActivityView.ACTION_ACTIVATE_PRO)
|
||||
.putExtra("uri", uri));
|
||||
|
||||
} else if (prefs.getBoolean("webview", false)) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString("link", url);
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ import java.io.InputStream;
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.mail.Address;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
|
@ -163,4 +165,27 @@ public class Helper {
|
|||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isPlayStoreInstall(Context context) {
|
||||
if (false && BuildConfig.DEBUG)
|
||||
return true;
|
||||
try {
|
||||
return "com.android.vending".equals(context.getPackageManager().getInstallerPackageName(context.getPackageName()));
|
||||
} catch (Throwable ex) {
|
||||
Log.e(TAG, Log.getStackTraceString(ex));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static String sha256(String data) throws NoSuchAlgorithmException {
|
||||
return sha256(data.getBytes());
|
||||
}
|
||||
|
||||
static String sha256(byte[] data) throws NoSuchAlgorithmException {
|
||||
byte[] bytes = MessageDigest.getInstance("SHA-256").digest(data);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : bytes)
|
||||
sb.append(String.format("%02x", b));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
10
app/src/main/res/drawable/baseline_monetization_on_24.xml
Normal file
10
app/src/main/res/drawable/baseline_monetization_on_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13.41,18.09L13.41,20h-2.67v-1.93c-1.71,-0.36 -3.16,-1.46 -3.27,-3.4h1.96c0.1,1.05 0.82,1.87 2.65,1.87 1.96,0 2.4,-0.98 2.4,-1.59 0,-0.83 -0.44,-1.61 -2.67,-2.14 -2.48,-0.6 -4.18,-1.62 -4.18,-3.67 0,-1.72 1.39,-2.84 3.11,-3.21L10.74,4h2.67v1.95c1.86,0.45 2.79,1.86 2.85,3.39L14.3,9.34c-0.05,-1.11 -0.64,-1.87 -2.22,-1.87 -1.5,0 -2.4,0.68 -2.4,1.64 0,0.84 0.65,1.39 2.67,1.91s4.18,1.39 4.18,3.91c-0.01,1.83 -1.38,2.83 -3.12,3.16z"/>
|
||||
</vector>
|
|
@ -35,6 +35,7 @@
|
|||
<string name="menu_operations">Operations</string>
|
||||
<string name="menu_legend">Legend</string>
|
||||
<string name="menu_faq">FAQ</string>
|
||||
<string name="menu_pro">Pro features</string>
|
||||
<string name="menu_privacy">Privacy</string>
|
||||
<string name="menu_about">About</string>
|
||||
<string name="menu_other">Other apps</string>
|
||||
|
@ -175,6 +176,9 @@
|
|||
<string name="title_legend_connected">Connected</string>
|
||||
<string name="title_legend_closing">Closing</string>
|
||||
|
||||
<string name="title_pro_valid">All pro features activated</string>
|
||||
<string name="title_pro_invalid">Invalid response</string>
|
||||
|
||||
<string name="title_debug_info">Debug info</string>
|
||||
<string name="title_debug_info_remark">Please describe the problem and indicate the time of the problem:</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue