diff --git a/OpenKeychain/src/main/AndroidManifest.xml b/OpenKeychain/src/main/AndroidManifest.xml index ae899dde2..82eb40ad3 100644 --- a/OpenKeychain/src/main/AndroidManifest.xml +++ b/OpenKeychain/src/main/AndroidManifest.xml @@ -149,8 +149,8 @@ - + @@ -200,8 +200,8 @@ - + @@ -221,6 +221,7 @@ + diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/FileHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/FileHelper.java index e42c7987b..615d89e0c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/FileHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/FileHelper.java @@ -26,18 +26,12 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Point; import android.net.Uri; -import android.os.Build; -import android.os.Environment; -import android.os.Handler; -import android.os.Message; -import android.os.Messenger; +import android.os.*; import android.provider.DocumentsContract; import android.provider.OpenableColumns; import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.widget.Toast; - import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; @@ -135,18 +129,25 @@ public class FileHelper { }, fragment.getActivity().getSupportFragmentManager(), title, message, defaultFile, checkMsg); } + @TargetApi(Build.VERSION_CODES.KITKAT) + public static void openDocument(Fragment fragment, String mimeType, int requestCode) { + openDocument(fragment, mimeType, false, requestCode); + } /** * Opens the storage browser on Android 4.4 or later for opening a file * @param fragment * @param mimeType can be text/plain for example + * @param multiple allow file chooser to return multiple files * @param requestCode used to identify the result coming back from storage browser onActivityResult() in your */ @TargetApi(Build.VERSION_CODES.KITKAT) - public static void openDocument(Fragment fragment, String mimeType, int requestCode) { + public static void openDocument(Fragment fragment, String mimeType, boolean multiple, int requestCode) { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType(mimeType); + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, multiple); + fragment.startActivityForResult(intent, requestCode); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java index 9e745215d..d1864f873 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/TemporaryStorageProvider.java @@ -104,6 +104,8 @@ public class TemporaryStorageProvider extends ContentProvider { @Override public String getType(Uri uri) { + // Note: If we can find a files mime type, we can decrypt it to temp storage and open it after + // encryption. The mime type is needed, else UI really sucks and some apps break. return "*/*"; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java index 5d82fca6a..e62591b1a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java @@ -23,7 +23,6 @@ import android.net.Uri; import android.os.Bundle; import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; - import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpHelper; @@ -120,6 +119,7 @@ public class DecryptActivity extends DrawerActivity { // override action action = ACTION_DECRYPT; + mFileFragmentBundle.putBoolean(DecryptFileFragment.ARG_FROM_VIEW_INTENT, true); } String textData = extras.getString(EXTRA_TEXT); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java index 520ef7567..dd05537ef 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFileFragment.java @@ -29,21 +29,21 @@ import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.TextView; - import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; -import org.sufficientlysecure.keychain.util.Notify; import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Notify; import java.io.File; public class DecryptFileFragment extends DecryptFragment { public static final String ARG_URI = "uri"; + public static final String ARG_FROM_VIEW_INTENT = "view_intent"; private static final int REQUEST_CODE_INPUT = 0x00007003; private static final int REQUEST_CODE_OUTPUT = 0x00007007; @@ -189,6 +189,15 @@ public class DecryptFileFragment extends DecryptFragment { deleteFileDialog.show(getActivity().getSupportFragmentManager(), "deleteDialog"); setInputUri(null); } + + /* + // A future open after decryption feature + if () { + Intent viewFile = new Intent(Intent.ACTION_VIEW); + viewFile.setData(mOutputUri); + startActivity(viewFile); + } + */ } } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java index 46462f924..2db6c232c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptMessageFragment.java @@ -27,9 +27,7 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.EditText; - import com.devspark.appmsg.AppMsg; - import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index ef999a449..3dea8f227 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -28,7 +28,6 @@ import android.os.Messenger; import android.support.v4.app.Fragment; import android.support.v4.view.PagerTabStrip; import android.support.v4.view.ViewPager; - import android.view.Menu; import android.view.MenuItem; import com.devspark.appmsg.AppMsg; @@ -41,8 +40,8 @@ import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter; +import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; -import org.sufficientlysecure.keychain.util.Choice; import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; @@ -220,9 +219,12 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn if (!isContentMessage() && mDeleteAfterEncrypt) { // TODO: Create and show dialog to delete original file - //DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment.newInstance(mInputUri); - //deleteFileDialog.show(getActivity().getSupportFragmentManager(), "deleteDialog"); - //setInputUri(null); + for (Uri inputUri : mInputUris) { + DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment.newInstance(inputUri); + deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); + } + mInputUris.clear(); + notifyUpdate(); } if (mShareAfterEncrypt) { @@ -327,12 +329,11 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn AppMsg.makeText(this, R.string.no_file_selected, AppMsg.STYLE_ALERT).show(); return false; } else if (mInputUris.size() > 1 && !mShareAfterEncrypt) { - AppMsg.makeText(this, "TODO", AppMsg.STYLE_ALERT).show(); // TODO + // This should be impossible... + return false; + } else if (mInputUris.size() != mOutputUris.size()) { + // This as well return false; - } - - if (mInputUris.size() != mOutputUris.size()) { - throw new IllegalStateException("Something went terribly wrong if this happens!"); } } @@ -445,6 +446,7 @@ public class EncryptActivity extends DrawerActivity implements EncryptActivityIn switch (item.getItemId()) { case R.id.check_use_symmetric: mSwitchToMode = item.isChecked() ? PAGER_MODE_SYMMETRIC : PAGER_MODE_ASYMMETRIC; + mViewPagerMode.setCurrentItem(mSwitchToMode); notifyUpdate(); break; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java index 9c7d7462f..47f4bdf59 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptAsymmetricFragment.java @@ -37,7 +37,6 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; -import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.ui.widget.EncryptKeyCompletionView; @@ -48,14 +47,9 @@ import java.util.Iterator; import java.util.List; public class EncryptAsymmetricFragment extends Fragment implements EncryptActivityInterface.UpdateListener { - private static final String SIGN_KEY_SELECTION = KeyRings.CAN_SIGN + " = 1 AND " + KeyRings.IS_REVOKED + " = 0"; - public static final String ARG_SIGNATURE_KEY_ID = "signature_key_id"; public static final String ARG_ENCRYPTION_KEY_IDS = "encryption_key_ids"; - public static final int REQUEST_CODE_PUBLIC_KEYS = 0x00007001; - public static final int REQUEST_CODE_SECRET_KEYS = 0x00007002; - ProviderHelper mProviderHelper; // view @@ -130,26 +124,6 @@ public class EncryptAsymmetricFragment extends Fragment implements EncryptActivi // preselect keys given by arguments (given by Intent to EncryptActivity) preselectKeys(signatureKeyId, encryptionKeyIds, mProviderHelper); - // TODO: Move this into widget! - - getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks() { - @Override - public Loader onCreateLoader(int id, Bundle args) { - return new CursorLoader(getActivity(), KeychainContract.KeyRings.buildUnifiedKeyRingsUri(), - new String[]{KeyRings.HAS_ENCRYPT, KeyRings.KEY_ID, KeyRings.USER_ID, KeyRings.FINGERPRINT}, - null, null, null); - } - - @Override - public void onLoadFinished(Loader loader, Cursor data) { - mEncryptKeyView.swapCursor(data); - } - - @Override - public void onLoaderReset(Loader loader) { - mEncryptKeyView.swapCursor(null); - } - }); getLoaderManager().initLoader(1, null, new LoaderManager.LoaderCallbacks() { @Override public Loader onCreateLoader(int id, Bundle args) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java index f782b7594..1125dce77 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFileFragment.java @@ -17,24 +17,27 @@ package org.sufficientlysecure.keychain.ui; +import android.annotation.TargetApi; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Point; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.*; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.FileHelper; import org.sufficientlysecure.keychain.helper.OtherHelper; -import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider; -import org.sufficientlysecure.keychain.util.Choice; import java.io.File; import java.util.List; @@ -89,45 +92,13 @@ public class EncryptFileFragment extends Fragment implements EncryptActivityInte mAddView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (Constants.KITKAT) { - FileHelper.openDocument(EncryptFileFragment.this, "*/*", REQUEST_CODE_INPUT); - } else { - FileHelper.openFile(EncryptFileFragment.this, - mEncryptInterface.getInputUris().isEmpty() ? null : mEncryptInterface.getInputUris().get(mEncryptInterface.getInputUris().size() - 1), "*/*", REQUEST_CODE_INPUT); - } + addInputUri(); } }); ListView listView = (ListView) view.findViewById(R.id.selected_files_list); listView.addFooterView(mAddView); listView.setAdapter(mAdapter); - /* - mFileCompression = (Spinner) view.findViewById(R.id.fileCompression); - Choice[] choices = new Choice[]{ - new Choice(Constants.choice.compression.none, getString(R.string.choice_none) + " (" - + getString(R.string.compression_fast) + ")"), - new Choice(Constants.choice.compression.zip, "ZIP (" - + getString(R.string.compression_fast) + ")"), - new Choice(Constants.choice.compression.zlib, "ZLIB (" - + getString(R.string.compression_fast) + ")"), - new Choice(Constants.choice.compression.bzip2, "BZIP2 (" - + getString(R.string.compression_very_slow) + ")"), - }; - ArrayAdapter adapter = new ArrayAdapter(getActivity(), - android.R.layout.simple_spinner_item, choices); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mFileCompression.setAdapter(adapter); - - - int defaultFileCompression = Preferences.getPreferences(getActivity()).getDefaultFileCompression(); - for (int i = 0; i < choices.length; ++i) { - if (choices[i].getId() == defaultFileCompression) { - mFileCompression.setSelection(i); - break; - } - } - */ - return view; } @@ -138,6 +109,16 @@ public class EncryptFileFragment extends Fragment implements EncryptActivityInte addInputUris(getArguments().getParcelableArrayList(ARG_URIS)); } + private void addInputUri() { + if (Constants.KITKAT) { + FileHelper.openDocument(EncryptFileFragment.this, "*/*", true, REQUEST_CODE_INPUT); + } else { + FileHelper.openFile(EncryptFileFragment.this, mEncryptInterface.getInputUris().isEmpty() ? + null : mEncryptInterface.getInputUris().get(mEncryptInterface.getInputUris().size() - 1), + "*/*", REQUEST_CODE_INPUT); + } + } + private void addInputUris(List uris) { if (uris != null) { for (Uri uri : uris) { @@ -206,25 +187,41 @@ public class EncryptFileFragment extends Fragment implements EncryptActivityInte (mEncryptInterface.isUseArmor() ? ".asc" : ".gpg"); mEncryptInterface.getOutputUris().add(TemporaryStorageProvider.createFile(getActivity(), targetName)); } - mEncryptInterface.startEncrypt(share); + mEncryptInterface.startEncrypt(true); } else if (mEncryptInterface.getInputUris().size() == 1) { showOutputFileDialog(); } } + @TargetApi(Build.VERSION_CODES.KITKAT) + public boolean handleClipData(Intent data) { + if (data.getClipData() != null && data.getClipData().getItemCount() > 0) { + for (int i = 0; i < data.getClipData().getItemCount(); i++) { + Uri uri = data.getClipData().getItemAt(i).getUri(); + if (uri != null) addInputUri(uri); + } + return true; + } + return false; + } + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_CODE_INPUT: { if (resultCode == Activity.RESULT_OK && data != null) { - addInputUri(data.getData()); + if (!Constants.KITKAT || !handleClipData(data)) { + addInputUri(data.getData()); + } } return; } case REQUEST_CODE_OUTPUT: { // This happens after output file was selected, so start our operation if (resultCode == Activity.RESULT_OK && data != null) { + mEncryptInterface.getOutputUris().clear(); mEncryptInterface.getOutputUris().add(data.getData()); + mEncryptInterface.notifyUpdate(); mEncryptInterface.startEncrypt(false); } return; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java index 2ba2e6497..7bdaf27c7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java @@ -4,6 +4,11 @@ import android.app.Activity; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; +import android.os.Bundle; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; @@ -48,8 +53,6 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { allowDuplicates(false); } - private EncryptKeyAdapter mAdapter; - @Override protected View getViewForObject(Object object) { if (object instanceof EncryptionKey) { @@ -81,6 +84,31 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { return null; } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (getContext() instanceof FragmentActivity) { + ((FragmentActivity) getContext()).getSupportLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks() { + @Override + public Loader onCreateLoader(int id, Bundle args) { + return new CursorLoader(getContext(), KeychainContract.KeyRings.buildUnifiedKeyRingsUri(), + new String[]{KeychainContract.KeyRings.HAS_ENCRYPT, KeychainContract.KeyRings.KEY_ID, KeychainContract.KeyRings.USER_ID, KeychainContract.KeyRings.FINGERPRINT}, + null, null, null); + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + swapCursor(data); + } + + @Override + public void onLoaderReset(Loader loader) { + swapCursor(null); + } + }); + } + } + public void swapCursor(Cursor cursor) { if (cursor == null) { setAdapter(new EncryptKeyAdapter(Collections.emptyList())); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NoSwipeWrapContentViewPager.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NoSwipeWrapContentViewPager.java index 08f071fb2..516e5ec39 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NoSwipeWrapContentViewPager.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NoSwipeWrapContentViewPager.java @@ -17,12 +17,13 @@ public class NoSwipeWrapContentViewPager extends android.support.v4.view.ViewPag @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int height = 0; - for(int i = 0; i < getChildCount(); i++) { - View child = getChildAt(i); + int height; + View child = getChildAt(getCurrentItem()); + if (child != null) { child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); - int h = child.getMeasuredHeight(); - if(h > height) height = h; + height = child.getMeasuredHeight(); + } else { + height = 0; } heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); diff --git a/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml b/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml index b5d7b98cd..74d723d69 100644 --- a/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml +++ b/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml @@ -1,13 +1,14 @@ - + + android:text="@string/from"/> + android:layout_gravity="center_vertical"/> diff --git a/OpenKeychain/src/main/res/layout/encrypt_content.xml b/OpenKeychain/src/main/res/layout/encrypt_content.xml index ec71b25e5..b2bdbf7b5 100644 --- a/OpenKeychain/src/main/res/layout/encrypt_content.xml +++ b/OpenKeychain/src/main/res/layout/encrypt_content.xml @@ -1,15 +1,17 @@ - + + android:id="@+id/encrypt_pager_mode" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> diff --git a/OpenKeychain/src/main/res/layout/encrypt_file_fragment.xml b/OpenKeychain/src/main/res/layout/encrypt_file_fragment.xml index 156fce8f0..3110b059e 100644 --- a/OpenKeychain/src/main/res/layout/encrypt_file_fragment.xml +++ b/OpenKeychain/src/main/res/layout/encrypt_file_fragment.xml @@ -10,17 +10,11 @@ android:paddingLeft="16dp" android:paddingRight="16dp" android:orientation="vertical"> - - - @@ -30,6 +24,8 @@ android:layout_height="1dip" android:background="?android:attr/listDivider"/> + + From Clipboard Encrypt and save file Encrypt and share file + Encrypt, sign and share Save Cancel Delete @@ -166,6 +167,7 @@ Secret Key: + From: None