From 5cba6c62d7b4628dfaf482dd883e333f93d323d4 Mon Sep 17 00:00:00 2001 From: Felix Bechstein Date: Sat, 22 Jul 2017 12:09:34 +0200 Subject: [PATCH] Parse username from password entry, refs #192 (#318) This is a first step of letting APS handle usernames from password entries. It shows the username in PgpHandler and allows to copy it to the clipboard. --- .../com/zeapo/pwdstore/PasswordEntryTest.java | 44 ++++++++++++ .../com/zeapo/pwdstore/PasswordEntry.java | 59 +++++++++++++++ .../pwdstore/autofill/AutofillService.java | 7 +- .../com/zeapo/pwdstore/crypto/PgpHandler.java | 61 ++++++++++------ .../res/drawable-hdpi/ic_content_copy.png | Bin 0 -> 422 bytes .../res/drawable-mdpi/ic_content_copy.png | Bin 0 -> 286 bytes .../res/drawable-xhdpi/ic_content_copy.png | Bin 0 -> 561 bytes .../res/drawable-xxhdpi/ic_content_copy.png | Bin 0 -> 821 bytes .../res/drawable-xxxhdpi/ic_content_copy.png | Bin 0 -> 1327 bytes .../main/res/layout/activity_pgp_handler.xml | 2 +- app/src/main/res/layout/decrypt_layout.xml | 67 +++++++++++++++--- app/src/main/res/layout/encrypt_layout.xml | 2 +- app/src/main/res/layout/key_id.xml | 2 +- app/src/main/res/menu/pgp_handler.xml | 6 +- app/src/main/res/values-cs/strings.xml | 2 +- app/src/main/res/values-de/strings.xml | 8 ++- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-ja/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-zh-rCH/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 8 ++- 23 files changed, 230 insertions(+), 49 deletions(-) create mode 100644 app/src/androidTest/java/com/zeapo/pwdstore/PasswordEntryTest.java create mode 100644 app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java create mode 100644 app/src/main/res/drawable-hdpi/ic_content_copy.png create mode 100644 app/src/main/res/drawable-mdpi/ic_content_copy.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_content_copy.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_content_copy.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_content_copy.png diff --git a/app/src/androidTest/java/com/zeapo/pwdstore/PasswordEntryTest.java b/app/src/androidTest/java/com/zeapo/pwdstore/PasswordEntryTest.java new file mode 100644 index 00000000..66636b1b --- /dev/null +++ b/app/src/androidTest/java/com/zeapo/pwdstore/PasswordEntryTest.java @@ -0,0 +1,44 @@ +package com.zeapo.pwdstore; + +import junit.framework.TestCase; + +public class PasswordEntryTest extends TestCase { + + public void testGetPassword() throws Exception { + assertEquals("fooooo", new PasswordEntry("fooooo\nbla\n").getPassword()); + assertEquals("fooooo", new PasswordEntry("fooooo\nbla").getPassword()); + assertEquals("fooooo", new PasswordEntry("fooooo\n").getPassword()); + assertEquals("fooooo", new PasswordEntry("fooooo").getPassword()); + assertEquals("", new PasswordEntry("\nblubb\n").getPassword()); + assertEquals("", new PasswordEntry("\nblubb").getPassword()); + assertEquals("", new PasswordEntry("\n").getPassword()); + assertEquals("", new PasswordEntry("").getPassword()); + } + + public void testGetExtraContent() throws Exception { + assertEquals("bla\n", new PasswordEntry("fooooo\nbla\n").getExtraContent()); + assertEquals("bla", new PasswordEntry("fooooo\nbla").getExtraContent()); + assertEquals("", new PasswordEntry("fooooo\n").getExtraContent()); + assertEquals("", new PasswordEntry("fooooo").getExtraContent()); + assertEquals("blubb\n", new PasswordEntry("\nblubb\n").getExtraContent()); + assertEquals("blubb", new PasswordEntry("\nblubb").getExtraContent()); + assertEquals("", new PasswordEntry("\n").getExtraContent()); + assertEquals("", new PasswordEntry("").getExtraContent()); + } + + public void testGetUsername() throws Exception { + assertEquals("username", new PasswordEntry("secret\nextra\nlogin: username\ncontent\n").getUsername()); + assertEquals("username", new PasswordEntry("\nextra\nusername: username\ncontent\n").getUsername()); + assertEquals("username", new PasswordEntry("\nUSERNaMe: username\ncontent\n").getUsername()); + assertEquals("username", new PasswordEntry("\nLOGiN:username").getUsername()); + assertNull(new PasswordEntry("secret\nextra\ncontent\n").getUsername()); + } + + public void testHasUsername() throws Exception { + assertTrue(new PasswordEntry("secret\nextra\nlogin: username\ncontent\n").hasUsername()); + assertFalse(new PasswordEntry("secret\nextra\ncontent\n").hasUsername()); + assertFalse(new PasswordEntry("secret\nlogin failed\n").hasUsername()); + assertFalse(new PasswordEntry("\n").hasUsername()); + assertFalse(new PasswordEntry("").hasUsername()); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java b/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java new file mode 100644 index 00000000..d4d3fe81 --- /dev/null +++ b/app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java @@ -0,0 +1,59 @@ +package com.zeapo.pwdstore; + +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; + +/** + * A single entry in password store. + */ +public class PasswordEntry { + + private static final String[] USERNAME_FIELDS = new String[]{"login", "username"}; + + private final String extraContent; + private final String password; + private final String username; + + public PasswordEntry(final ByteArrayOutputStream os) throws UnsupportedEncodingException { + this(os.toString("UTF-8")); + } + + public PasswordEntry(final String decryptedContent) { + final String[] passContent = decryptedContent.split("\n", 2); + password = passContent[0]; + extraContent = passContent.length > 1 ? passContent[1] : ""; + username = findUsername(); + } + + public String getPassword() { + return password; + } + + public String getExtraContent() { + return extraContent; + } + + public String getUsername() { + return username; + } + + public boolean hasExtraContent() { + return extraContent.length() != 0; + } + + public boolean hasUsername() { + return username != null; + } + + private String findUsername() { + final String[] extraLines = extraContent.split("\n"); + for (String line : extraLines) { + for (String field : USERNAME_FIELDS) { + if (line.toLowerCase().startsWith(field + ":")) { + return line.split(": *", 2)[1]; + } + } + } + return null; + } +} diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java index 447f39f3..004a0bbd 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java @@ -23,6 +23,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityWindowInfo; import android.widget.Toast; +import com.zeapo.pwdstore.PasswordEntry; import com.zeapo.pwdstore.R; import com.zeapo.pwdstore.utils.PasswordRepository; @@ -492,7 +493,7 @@ public class AutofillService extends AccessibilityService { switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { case OpenPgpApi.RESULT_CODE_SUCCESS: { try { - String[] passContent = os.toString("UTF-8").split("\n"); + final PasswordEntry entry = new PasswordEntry(os); // if the user focused on something else, take focus back // but this will open another dialog...hack to ignore this @@ -501,11 +502,11 @@ public class AutofillService extends AccessibilityService { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Bundle args = new Bundle(); args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, - passContent[0]); + entry.getPassword()); info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args); } else { ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("autofill_pm", passContent[0]); + ClipData clip = ClipData.newPlainText("autofill_pm", entry.getPassword()); clipboard.setPrimaryClip(clip); info.performAction(AccessibilityNodeInfo.ACTION_PASTE); diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java index 232c7b94..e938fdd4 100644 --- a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java +++ b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpHandler.java @@ -34,6 +34,7 @@ import android.widget.Toast; import com.google.common.primitives.Longs; import com.zeapo.pwdstore.BuildConfig; +import com.zeapo.pwdstore.PasswordEntry; import com.zeapo.pwdstore.R; import com.zeapo.pwdstore.SelectFolderFragment; import com.zeapo.pwdstore.UserPreference; @@ -163,7 +164,7 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne finish(); return true; case R.id.copy_password: - copyToClipBoard(); + copyPasswordToClipBoard(); break; case R.id.share_password_as_plaintext: shareAsPlaintext(); @@ -245,7 +246,7 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_plaintext_password_to)));//Always show a picker to give the user a chance to cancel } - public void copyToClipBoard() { + public void copyPasswordToClipBoard() { if (findViewById(R.id.crypto_password_show) == null) return; @@ -261,7 +262,13 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne } catch (NumberFormatException e) { // ignore and keep default } - showToast(this.getResources().getString(R.string.clipboard_toast_text, clearAfter)); + showToast(this.getResources().getString(R.string.clipboard_password_toast_text, clearAfter)); + } + + public void copyUsernameToClipBoard(final String username) { + ClipData clip = ClipData.newPlainText("pgp_handler_result_pm", username); + clipboard.setPrimaryClip(clip); + showToast(this.getResources().getString(R.string.clipboard_username_toast_text)); } public void handleClick(View view) { @@ -490,34 +497,46 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne findViewById(R.id.crypto_container).setVisibility(View.VISIBLE); Typeface monoTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodepro.ttf"); - final String[] passContent = os.toString("UTF-8").split("\n", 2); - final String decodedPassword = passContent[0]; - final String extraContent = passContent.length > 1 ? passContent[1] : ""; - textViewPassword - .setTypeface(monoTypeface); - textViewPassword - .setText(decodedPassword); + final PasswordEntry entry = new PasswordEntry(os); + textViewPassword.setTypeface(monoTypeface); + textViewPassword.setText(entry.getPassword()); Button toggleVisibilityButton = (Button) findViewById(R.id.crypto_password_toggle_show); toggleVisibilityButton.setVisibility(showPassword?View.GONE:View.VISIBLE); textViewPassword.setTransformationMethod(showPassword?null:new HoldToShowPasswordTransformation(toggleVisibilityButton, new Runnable() { @Override public void run() { - textViewPassword - .setText(decodedPassword); + textViewPassword.setText(entry.getPassword()); } })); - if (extraContent.length() != 0) { + if (entry.hasExtraContent()) { findViewById(R.id.crypto_extra_show_layout).setVisibility(showExtraContent ? View.VISIBLE : View.GONE); - ((TextView) findViewById(R.id.crypto_extra_show)) - .setTypeface(monoTypeface); - ((TextView) findViewById(R.id.crypto_extra_show)) - .setText(extraContent); + final TextView extraView = (TextView) findViewById(R.id.crypto_extra_show); + extraView.setTypeface(monoTypeface); + extraView.setText(entry.getExtraContent()); + if (entry.hasUsername()) { + findViewById(R.id.crypto_username_show).setVisibility(View.VISIBLE); + findViewById(R.id.crypto_username_show_label).setVisibility(View.VISIBLE); + findViewById(R.id.crypto_copy_username).setVisibility(View.VISIBLE); + findViewById(R.id.crypto_copy_username).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + copyUsernameToClipBoard(entry.getUsername()); + } + }); + final TextView usernameView = (TextView) findViewById(R.id.crypto_username_show); + usernameView.setTypeface(monoTypeface); + usernameView.setText(entry.getUsername()); + } else { + findViewById(R.id.crypto_username_show).setVisibility(View.GONE); + findViewById(R.id.crypto_username_show_label).setVisibility(View.GONE); + findViewById(R.id.crypto_copy_username).setVisibility(View.GONE); + } } if (settings.getBoolean("copy_on_decrypt", true)) { - copyToClipBoard(); + copyPasswordToClipBoard(); } } else { Log.d("PGPHANDLER", "Error message after decrypt : " + os.toString()); @@ -569,12 +588,12 @@ public class PgpHandler extends AppCompatActivity implements OpenPgpServiceConne findViewById(R.id.crypto_container).setVisibility(View.VISIBLE); Typeface monoTypeface = Typeface.createFromAsset(getAssets(), "fonts/sourcecodepro.ttf"); - String[] passContent = os.toString("UTF-8").split("\n"); + final PasswordEntry entry = new PasswordEntry(os); + decodedPassword = entry.getPassword(); textViewPassword .setTypeface(monoTypeface); textViewPassword - .setText(passContent[0]); - decodedPassword = passContent[0]; + .setText(decodedPassword); String extraContent = os.toString("UTF-8").replaceFirst(".*\n", ""); if (extraContent.length() != 0) { diff --git a/app/src/main/res/drawable-hdpi/ic_content_copy.png b/app/src/main/res/drawable-hdpi/ic_content_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..92cdb3efbe5af837b78b0f46a96ad2628d055718 GIT binary patch literal 422 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezr3(Fy?x?IEG|6znyOD#o{Q?y8o;C zq+TD9k79BT1`!_^;+#zkj4z%M&UmKlV`lV)Ax(<&of?-`lY$njtu)V?kkV4)p0L9P z!h2S&`yS_e_DjRO^^WIXt8hNE8=>=$IpI8$V&K6HhbFvz70ttgMsv15>n{kg9O>*2VvYPfMQsDuiPXsa z11vu_v6$YN#ImjN?i{5C>jz5e+f*8B6PPOuw@i7X-*@uwifpF#15yQ?ceJ`Anfw@b zvNJBtFpe;Go2@Cr7a=NAb8@n@UGS%f7?BZA$C*#PtU<{c=uq@z>d2PlGYXmS)HLexTVco)wr zk{9f5ygQ!ffB$=)yG+3&D>%OdkPIXPu?DJW;v~?vD?H%sC#@X|&_WHbSno)%nSaFW z5CAuL#{gd_MaAY!i|4{(Q1yaa-uV*}AU1V9_l7zKh~ z;}qQlkPIA+fy-@MP0%T#3-TuK|2@F%_8FcA3hWGX^#7^|^Kt69LM0IV1H+iFIrcBu kcaUGNCxB!i87SPqH(4`AAv#*aoFbMr9FAi7)!^2AV0%L{^PCKpFU;QeZi|1AmH1;;Ak-0f^-d6@ z@PRGgD_CMezsCJ!PX8|e5}efFnQ*H54ujw7s`btMNkSJ`cEq3f!4Ok5vsZ$}LVoc9 zjtc@3KaDpeN6ID%7;v0nJli-~fA)Pw?E|w}<9L|F8Wi>KPG{iU&am!$LGtBQPDd0H zZhmL;KcH1Gx%la^2Fd*0>@rV|{7hG4(uw#Y5t$mm6~OgpF8>zx4B-&b0Lc*f1#TX5 z7epn_Wi8rvzqDQ=i}}{yCvuJD|MwfDH?COZ{4 zKLwd&*PU}WH()4X`B5@?KkKC=#&xhHrsu17|O1vj-!m{yfhY eK?FE|7z7(OId<*-eHEA#7(8A5T-G@yGywnt<>X-i literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_content_copy.png b/app/src/main/res/drawable-xxhdpi/ic_content_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..6d24f43410d6e5bd5661cafeee34af21c32ab0eb GIT binary patch literal 821 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>VEW_f;uum9_jZo;dY?dvw)xF1 z9UO{QyAanB z_Woj{^INLdzrXvs_S^5Zk=5tyw10G3Z4e3#mtkzlXJX_~c;gUpkA*@?$FRZnKwZLX z2Dv@Var_G|M=MQjNIp=Q5d2;{?ta7b1I=G~bFH-)A8-_`db=eoRNNu;q-a7r!#|4& z9tV0EqtDOS%(>#-kJ+L>&L8;7c{7x69ywLDShAGpwY>{VdxybFn@ITkF zz2UIK%?-JEFD|=3;Qb)-<5oa=)=O7khnp+rO5Et-KOpul@n8P58PZ;c2j#!{*tYU*BU$-^c$*s zeQxr_2p`!0j%&fiyJmW~w+f3jFi2SkOuf(1y&?O+ocHX}6F7goZn)pH%%-nQa9;80 znL6p*n^%DPxRaxcC_fE=dSEdU0FW&tu+$?MN>dE_-wn*3=dQawzS^PUJ-e(Z>8|YHpR_zH+68{Fv?=KPM;n1{^HZS4ebXu-&0PP*wDdn zs^nC**Yd`_#%I=^zi_Eaj@kbg&#dD+ySWyeS*!B!!3*7!)2>I#aqMHdcmD8&eWp=< uYu<0wdHR!yBU!wG;SgWTQ(vl3^^ESXZY5Sa>=giJ2L?}9KbLh*2~7ZPsB$X+ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_content_copy.png b/app/src/main/res/drawable-xxxhdpi/ic_content_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..0949977cf66192177e0f6241a8c06e47d92a0ae0 GIT binary patch literal 1327 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVEN|h;uum9_ja!JY0+?zHu?1} z3yyGWbSfk{1hJ|tW#Nh2u-Qi;p({jeTa*WfnIcP2cjly^Kg=sxR$ozK@eve}4iw?_ zG+=X#EZ8Ia?8H6e>T5dbdxPIcPEX%^-@5vo<^3~KB}>#csFi-tlH*j^$)Uo)sbJao z~U|Oj02O0pF-vDBAO^TBz%J*hslg><(K*gjuWETrVHL> zv}3Vjy%*o1;I!AgaX#B*ejx>>3!xfzOnwZnn>SR&9pimavtd@%bm35j=!W%;bN5<_9X{qT#dgca`@dTO-7fQM_fuh7=#=9CxtO}7}@l=;##IL=5q$rcM7U_YRl5Ua6iy?F9;2H^u&GfdApGPpM$zIdSQ%4hWg z#i+T(0u7P-W0|J)-&b$S_4&^9Ugzn5aSQW6U+v5L-ZE|YwV&Zzc}Yc?(v5GYmrg#= zxAf08#Xo6_W(9FQ_~Np`mtmWF`U6C~6S$D$RbvP`c*{18>DwK1KEyy?IYN ziyGK`wz6k1Y*cBHS)GnX9QPlA51kmsU zA?1wt)yKL0S*Kia-MH#&zasN;fvb$W{@wg6|Db)S zF_;kY^W`pHopjTRr7{T$PO(gEOm8e=`7X?Rd8(tRp>e}g24==njJKHAbZW4#Sa@|~ z7@vW_0+|K22WA1KrJ_#CJb2__R_nk0`W;!ud(m7UIDTx)zp(LK^=*B|V^1v#5_BAR zAKzoF%aK^`xx$j;LGpvs3)au5wp+6NfartkYQfnODSS*D%DL-V-(;UyTB=c9en9`g z-fNBR$7VM(^fcOP-jO@Mt6F1%;JNMl|IKfFt$ajIrbv&;K;U+Rb2q!`ZExjeH8p#9 z@0!(aZ#>gGHd!$gk9s z!EeFhWfK_|`5jxS$9aIWvs;TJ11RT@@IE?ni!RKO%_+DltYUQ0IL XWtecTbP0l+XkK^jav# literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/activity_pgp_handler.xml b/app/src/main/res/layout/activity_pgp_handler.xml index 3c79b37d..71dcff3e 100644 --- a/app/src/main/res/layout/activity_pgp_handler.xml +++ b/app/src/main/res/layout/activity_pgp_handler.xml @@ -8,7 +8,7 @@ android:paddingBottom="@dimen/activity_vertical_margin" tools:context="com.zeapo.pwdstore.crypto.PgpHandler" android:orientation="vertical" - android:background="#eee"> + android:background="@color/background"> + android:background="@color/background"> - - + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" + android:layout_alignParentTop="true" + android:contentDescription="@string/copy_username" + android:background="@color/background" + android:src="@drawable/ic_content_copy"/> + + + + android:textIsSelectable="true" + android:typeface="monospace" /> - + + + + + diff --git a/app/src/main/res/layout/encrypt_layout.xml b/app/src/main/res/layout/encrypt_layout.xml index 98a6b04d..30ccfba4 100644 --- a/app/src/main/res/layout/encrypt_layout.xml +++ b/app/src/main/res/layout/encrypt_layout.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" android:orientation="vertical" tools:context="com.zeapo.pwdstore.crypto.PgpHandler" - android:background="#eee" + android:background="@color/background" android:padding="@dimen/activity_horizontal_margin"> + android:background="@color/background"> - - - Nebyl vybrán poskytovatel OpenPGP! Čekání na OpenKeychain… - Heslo zkopírováno do schránky, máte %d sekund na jeho zkopírování. + Heslo zkopírováno do schránky, máte %d sekund na jeho zkopírování. Až to bude možné, tak si zadejte jméno účtu v nastavení Zadejte si v nastavení svůj OpenKeychain účet (email) Jméno účtu je prázdné! diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 6b1161d1..cfb2d2d2 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -30,7 +30,8 @@ Kein OpenPGP-Provider ausgewählt! Warte auf OpenKeychain… - Passwort ist in der Zwischen ablage, du hast %d Sekunden, um es einzufügen. + Passwort ist in der Zwischenablage, du hast %d Sekunden, um es einzufügen. + Benutzername ist in der Zwischenablage Bitte setze deinen Accountnamen in den Einstellungen. Bitte setze deinen OpenKeychain Account (E-Mail) in den Einstellungen Accountname ist leer! @@ -88,6 +89,11 @@ Suche Passwort: Weiterer Inhalt: + Benutzername: + Passwort bearbeiten + Passwort kopieren + Benutzername kopieren + Als Klartext teilen Git diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 6fd7ab11..d496f79a 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -31,7 +31,7 @@ Aucun prestataire OpenPGP sélectionné! Attente de OpenKeychain… - Mot de passe copié dans le presse papier, vous avez %d secondes pour coller celui-ci. + Mot de passe copié dans le presse papier, vous avez %d secondes pour coller celui-ci. Renseignez le nom de votre compte dans les paramètres dès que vous pouvez Renseignez votre compte OpenKeychain (email) dans les préférences Nom du compte absent! diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 764dc004..5c15f3eb 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -31,7 +31,7 @@ OpenPGP プロバイダが選択されていません! OpenKeychain の待機中… - パスワードをクリップボードにコピーしました %d 秒以内に張り付けしてください。 + パスワードをクリップボードにコピーしました %d 秒以内に張り付けしてください。 できるだけ設定に毎回アカウント名を設定してください プリファレンスに OpenKeychain アカウント (メールアドレス) を設定してください アカウント名が空です! diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 4c8510e6..e2711cc3 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -31,7 +31,7 @@ Не выбран поставщик OpenPGP! Ожидание OpenKeychain… - Пароль скопирован в буфер обмена, у вас есть %d секунд чтобы вставить его. + Пароль скопирован в буфер обмена, у вас есть %d секунд чтобы вставить его. Пожалуйста, задайте имя пользователя в настройках Пожалуйста, задайте почту для OpenKeychain в настройках Пустое имя пользователя! diff --git a/app/src/main/res/values-zh-rCH/strings.xml b/app/src/main/res/values-zh-rCH/strings.xml index d5cad54f..997914a4 100644 --- a/app/src/main/res/values-zh-rCH/strings.xml +++ b/app/src/main/res/values-zh-rCH/strings.xml @@ -15,7 +15,7 @@ 在app中自动输入密码. 此功能只在 Andorid 4.3 及以上版本中可用. 在 Andorid 5.0 及以上版本中不依赖剪贴板 输入 “类别:\" - 密码已复制到剪贴板, 你有 %d 秒的时间将其粘贴到其他地方. + 密码已复制到剪贴板, 你有 %d 秒的时间将其粘贴到其他地方. 从服务器Clone 欢迎使用 Password Store 你可以选择创建新的版本库或将你已有的 git 版本库克隆到你的设备上 Clone diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 1e6db97e..088ab0be 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -15,7 +15,7 @@ 在app中自動填入密碼. 此功能只能在 Andorid 4.3 及以上版本中使用. 在 Andorid 5.0 及以上版本中不需要剪貼簿 輸入 “分類:\" - 密碼已複製到剪貼簿, 你有 %d 秒的時間將其貼上到其他地方. + 密碼已複製到剪貼簿, 你有 %d 秒的時間將其貼上到其他地方. 從伺服器 Clone 歡迎使用 Password Store 你可以選擇建立新的 Repo 或將你已有的 git repo clone 到你的裝置上 Clone diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 96ebf1bb..7e1e3814 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,6 +1,7 @@ #ff7043 + #eee #fde0dc #f9bdbb diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 444bbf08..51b23002 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,7 +32,8 @@ No OpenPGP Provider selected! Waiting for OpenKeychain… - Password copied to clipboard, you have %d seconds to paste it somewhere. + Password copied to clipboard, you have %d seconds to paste it somewhere. + Username copied to clipboard Please set your account name in settings whenever you can Please set your OpenKeychain account (email) in the preferences Account name empty! @@ -97,6 +98,11 @@ Search Password: Extra content: + Username: + Edit password + Copy password + Copy username + Share as plaintext Git