diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a2bf533c..22beee29 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -95,6 +95,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java b/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java
index f1cc81b2..11358f1c 100644
--- a/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java
+++ b/app/src/main/java/org/fedorahosted/freeotp/MainActivity.java
@@ -40,10 +40,15 @@
import org.fedorahosted.freeotp.add.ScanActivity;
import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.database.DataSetObserver;
import android.net.Uri;
import android.os.Bundle;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
@@ -51,6 +56,8 @@
import android.view.WindowManager.LayoutParams;
import android.widget.GridView;
+import com.google.gson.Gson;
+
public class MainActivity extends Activity implements OnMenuItemClickListener {
private TokenAdapter mTokenAdapter;
private DataSetObserver mDataSetObserver;
@@ -132,8 +139,126 @@ public boolean onMenuItemClick(MenuItem item) {
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
- Uri uri = intent.getData();
- if (uri != null)
- TokenPersistence.addWithToast(this, uri.toString());
+ final Uri uri = intent.getData();
+ if (uri != null) {
+ String action = intent.getAction();
+ if (action.equals(Intent.ACTION_VIEW)) {
+ TokenPersistence.addWithToast(this, uri.toString());
+ return;
+ }
+ try {
+ final Token token = new Token(uri);
+ final String key = token.getID();
+ final Intent out = new Intent();
+ out.putExtra("key", key);
+ String appname = intent.getStringExtra("appname");
+ if (appname == null) {
+ appname = getString(R.string.default_appname);
+ }
+ final SharedPreferences prefs = getSharedPreferences(TokenPersistence.NAME, Context.MODE_PRIVATE);
+ switch (action) {
+ case Intent.ACTION_GET_CONTENT:
+ if (prefs.contains(key)) {
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.attention)
+ .setMessage(appname + getString(R.string.request_code) + "\"" + key + "\"")
+ .setCancelable(false)
+ .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ out.putExtra("currentCode", new Gson().fromJson(prefs.getString(key, null), Token.class).generateCodes().getCurrentCode());
+ setResult(Activity.RESULT_OK, out);
+ finish();
+ }
+ })
+ .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ setResult(Activity.RESULT_CANCELED, out);
+ finish();
+ }
+ })
+ .show()
+ ;
+ } else {
+ setResult(Activity.RESULT_CANCELED, out);
+ finish();
+ }
+ break;
+ case Intent.ACTION_INSERT:
+ if (prefs.contains(key)) {
+ new AlertDialog.Builder(MainActivity.this)
+ .setTitle(R.string.error)
+ .setMessage(String.format(getString(R.string.token_already_exists), key))
+ .setCancelable(false)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ setResult(Activity.RESULT_CANCELED, out);
+ finish();
+ }
+ })
+ .show()
+ ;
+ } else {
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.attention)
+ .setMessage(appname + getString(R.string.request_install_token) + "\"" + key + "\"")
+ .setCancelable(false)
+ .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ try {
+ new TokenPersistence(MainActivity.this).add(token);
+ out.putExtra("currentCode", token.generateCodes().getCurrentCode());
+ out.putExtra("secret", uri.getQueryParameter("secret"));
+ setResult(Activity.RESULT_OK, out);
+ finish();
+ } catch (Token.TokenUriInvalidException e) {
+ new AlertDialog.Builder(MainActivity.this)
+ .setTitle(R.string.error)
+ .setMessage(getString(R.string.bad_token_uri) + uri.toString())
+ .setCancelable(false)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ setResult(Activity.RESULT_CANCELED, out);
+ finish();
+ }
+ })
+ .show()
+ ;
+ }
+ }
+ })
+ .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ setResult(Activity.RESULT_CANCELED, out);
+ finish();
+ }
+ })
+ .show()
+ ;
+ }
+ break;
+ default:
+ Log.e("LOG", "bad action: " + action);
+ }
+ } catch (Token.TokenUriInvalidException e) {
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.error)
+ .setMessage(getString(R.string.bad_token_uri) + uri.toString())
+ .setCancelable(false)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ finish();
+ }
+ })
+ .show()
+ ;
+ }
+ }
}
}
diff --git a/app/src/main/java/org/fedorahosted/freeotp/TokenPersistence.java b/app/src/main/java/org/fedorahosted/freeotp/TokenPersistence.java
index 3d450f90..8c4ba378 100644
--- a/app/src/main/java/org/fedorahosted/freeotp/TokenPersistence.java
+++ b/app/src/main/java/org/fedorahosted/freeotp/TokenPersistence.java
@@ -8,7 +8,6 @@
import android.content.Context;
import android.content.SharedPreferences;
-import android.net.Uri;
import android.widget.Toast;
import com.google.gson.Gson;
@@ -16,7 +15,7 @@
import com.google.gson.reflect.TypeToken;
public class TokenPersistence {
- private static final String NAME = "tokens";
+ protected static final String NAME = "tokens";
private static final String ORDER = "tokenOrder";
private final SharedPreferences prefs;
private final Gson gson;
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index de39f413..3f6b2970 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -38,6 +38,16 @@
This is your last chance: if you delete this token, it will be gone forever. It will not be disabled on the server.
Delete this token?
+ Attention
+ Error
+ Allow
+ Deny
+ An unspecified app
+ " has requested a code for token "
+ " has requested to install a token for "
+ "Bad token uri: "
+ Token \"%s\" already exists
+
- MD5
- SHA1