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.
This commit is contained in:
parent
6ce31056c9
commit
5cba6c62d7
23 changed files with 230 additions and 49 deletions
|
@ -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());
|
||||
}
|
||||
}
|
59
app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java
Normal file
59
app/src/main/java/com/zeapo/pwdstore/PasswordEntry.java
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
BIN
app/src/main/res/drawable-hdpi/ic_content_copy.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_content_copy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 422 B |
BIN
app/src/main/res/drawable-mdpi/ic_content_copy.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_content_copy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 286 B |
BIN
app/src/main/res/drawable-xhdpi/ic_content_copy.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_content_copy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 561 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_content_copy.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_content_copy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 821 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_content_copy.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_content_copy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -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">
|
||||
|
||||
<GridLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
android:layout_height="match_parent"
|
||||
tools:context="com.zeapo.pwdstore.crypto.PgpHandler"
|
||||
android:orientation="vertical"
|
||||
android:background="#eee">
|
||||
android:background="@color/background">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
|
@ -99,28 +99,73 @@
|
|||
android:layout_columnSpan="3"/>
|
||||
</GridLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/crypto_extra_show_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="invisible">
|
||||
|
||||
<TextView
|
||||
<ImageButton
|
||||
android:id="@+id/crypto_copy_username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@android:color/black"
|
||||
android:text="@string/extra_content"/>
|
||||
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"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/crypto_extra_show"
|
||||
android:textIsSelectable="true"
|
||||
android:id="@+id/crypto_username_show_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_toLeftOf="@id/crypto_copy_username"
|
||||
android:layout_toEndOf="@id/crypto_copy_username"
|
||||
android:text="@string/username"
|
||||
android:textColor="@android:color/black"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/crypto_username_show"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@id/crypto_username_show_label"
|
||||
android:layout_toLeftOf="@id/crypto_copy_username"
|
||||
android:layout_toEndOf="@id/crypto_copy_username"
|
||||
android:textColor="@android:color/black"
|
||||
android:typeface="monospace"/>
|
||||
android:textIsSelectable="true"
|
||||
android:typeface="monospace" />
|
||||
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/crypto_extra_show_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@id/crypto_username_show"
|
||||
android:text="@string/extra_content"
|
||||
android:textColor="@android:color/black"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/crypto_extra_show"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@id/crypto_extra_show_label"
|
||||
android:textColor="@android:color/black"
|
||||
android:textIsSelectable="true"
|
||||
android:typeface="monospace" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -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">
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:background="#eee">
|
||||
android:background="@color/background">
|
||||
|
||||
<GridLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -2,17 +2,17 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:pwstore="http://schemas.android.com/apk/res-auto"
|
||||
tools:context="com.zeapo.pwdstore.crypto.PgpHandler" >
|
||||
<item android:title="Share as plaintext"
|
||||
<item android:title="@string/share_as_plaintext"
|
||||
android:icon="@drawable/ic_share_white_24dp"
|
||||
pwstore:showAsAction="ifRoom"
|
||||
android:id="@+id/share_password_as_plaintext"
|
||||
/>
|
||||
<item android:title="Copy password"
|
||||
<item android:title="@string/copy_password"
|
||||
android:icon="@drawable/ic_content_copy_white_24dp"
|
||||
pwstore:showAsAction="ifRoom"
|
||||
android:id="@+id/copy_password"
|
||||
/>
|
||||
<item android:title="Edit password"
|
||||
<item android:title="@string/edit_password"
|
||||
android:icon="@drawable/ic_edit_white_24dp"
|
||||
pwstore:showAsAction="ifRoom"
|
||||
android:id="@+id/edit_password"
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<!-- PGPHandler -->
|
||||
<string name="provider_toast_text">Nebyl vybrán poskytovatel OpenPGP!</string>
|
||||
<string name="okc_progress_text">Čekání na OpenKeychain…</string>
|
||||
<string name="clipboard_toast_text">Heslo zkopírováno do schránky, máte %d sekund na jeho zkopírování.</string>
|
||||
<string name="clipboard_password_toast_text">Heslo zkopírováno do schránky, máte %d sekund na jeho zkopírování.</string>
|
||||
<string name="name_settings_toast_text">Až to bude možné, tak si zadejte jméno účtu v nastavení</string>
|
||||
<string name="account_settings_dialog_text">Zadejte si v nastavení svůj OpenKeychain účet (email)</string>
|
||||
<string name="account_settings_dialog_title">Jméno účtu je prázdné!</string>
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
<!-- PGPHandler -->
|
||||
<string name="provider_toast_text">Kein OpenPGP-Provider ausgewählt!</string>
|
||||
<string name="okc_progress_text">Warte auf OpenKeychain…</string>
|
||||
<string name="clipboard_toast_text">Passwort ist in der Zwischen ablage, du hast %d Sekunden, um es einzufügen.</string>
|
||||
<string name="clipboard_password_toast_text">Passwort ist in der Zwischenablage, du hast %d Sekunden, um es einzufügen.</string>
|
||||
<string name="clipboard_username_toast_text">Benutzername ist in der Zwischenablage</string>
|
||||
<string name="name_settings_toast_text">Bitte setze deinen Accountnamen in den Einstellungen.</string>
|
||||
<string name="account_settings_dialog_text">Bitte setze deinen OpenKeychain Account (E-Mail) in den Einstellungen</string>
|
||||
<string name="account_settings_dialog_title">Accountname ist leer!</string>
|
||||
|
@ -88,6 +89,11 @@
|
|||
<string name="action_search">Suche</string>
|
||||
<string name="password">Passwort:</string>
|
||||
<string name="extra_content">Weiterer Inhalt:</string>
|
||||
<string name="username">Benutzername:</string>
|
||||
<string name="edit_password">Passwort bearbeiten</string>
|
||||
<string name="copy_password">Passwort kopieren</string>
|
||||
<string name="copy_username">Benutzername kopieren</string>
|
||||
<string name="share_as_plaintext">Als Klartext teilen</string>
|
||||
|
||||
<!-- Preferences -->
|
||||
<string name="pref_git_title">Git</string>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<!-- PGPHandler -->
|
||||
<string name="provider_toast_text">Aucun prestataire OpenPGP sélectionné!</string>
|
||||
<string name="okc_progress_text">Attente de OpenKeychain…</string>
|
||||
<string name="clipboard_toast_text">Mot de passe copié dans le presse papier, vous avez %d secondes pour coller celui-ci.</string>
|
||||
<string name="clipboard_password_toast_text">Mot de passe copié dans le presse papier, vous avez %d secondes pour coller celui-ci.</string>
|
||||
<string name="name_settings_toast_text">Renseignez le nom de votre compte dans les paramètres dès que vous pouvez</string>
|
||||
<string name="account_settings_dialog_text">Renseignez votre compte OpenKeychain (email) dans les préférences</string>
|
||||
<string name="account_settings_dialog_title">Nom du compte absent!</string>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<!-- PGPHandler -->
|
||||
<string name="provider_toast_text">OpenPGP プロバイダが選択されていません!</string>
|
||||
<string name="okc_progress_text">OpenKeychain の待機中…</string>
|
||||
<string name="clipboard_toast_text">パスワードをクリップボードにコピーしました %d 秒以内に張り付けしてください。</string>
|
||||
<string name="clipboard_password_toast_text">パスワードをクリップボードにコピーしました %d 秒以内に張り付けしてください。</string>
|
||||
<string name="name_settings_toast_text">できるだけ設定に毎回アカウント名を設定してください</string>
|
||||
<string name="account_settings_dialog_text">プリファレンスに OpenKeychain アカウント (メールアドレス) を設定してください</string>
|
||||
<string name="account_settings_dialog_title">アカウント名が空です!</string>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<!-- PGPHandler -->
|
||||
<string name="provider_toast_text">Не выбран поставщик OpenPGP!</string>
|
||||
<string name="okc_progress_text">Ожидание OpenKeychain…</string>
|
||||
<string name="clipboard_toast_text">Пароль скопирован в буфер обмена, у вас есть %d секунд чтобы вставить его.</string>
|
||||
<string name="clipboard_password_toast_text">Пароль скопирован в буфер обмена, у вас есть %d секунд чтобы вставить его.</string>
|
||||
<string name="name_settings_toast_text">Пожалуйста, задайте имя пользователя в настройках</string>
|
||||
<string name="account_settings_dialog_text">Пожалуйста, задайте почту для OpenKeychain в настройках</string>
|
||||
<string name="account_settings_dialog_title">Пустое имя пользователя!</string>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<string name="autofill_description">在app中自动输入密码. 此功能只在 Andorid 4.3 及以上版本中可用. 在 Andorid 5.0 及以上版本中不依赖剪贴板</string>
|
||||
<string name="autofill_fill">输入</string>
|
||||
<string name="category_string">“类别:\"</string>
|
||||
<string name="clipboard_toast_text">密码已复制到剪贴板, 你有 %d 秒的时间将其粘贴到其他地方.</string>
|
||||
<string name="clipboard_password_toast_text">密码已复制到剪贴板, 你有 %d 秒的时间将其粘贴到其他地方.</string>
|
||||
<string name="clone">从服务器Clone</string>
|
||||
<string name="clone_fragment_text">欢迎使用 Password Store 你可以选择创建新的版本库或将你已有的 git 版本库克隆到你的设备上</string>
|
||||
<string name="clone_settings">Clone</string>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<string name="autofill_description">在app中自動填入密碼. 此功能只能在 Andorid 4.3 及以上版本中使用. 在 Andorid 5.0 及以上版本中不需要剪貼簿</string>
|
||||
<string name="autofill_fill">輸入</string>
|
||||
<string name="category_string">“分類:\"</string>
|
||||
<string name="clipboard_toast_text">密碼已複製到剪貼簿, 你有 %d 秒的時間將其貼上到其他地方.</string>
|
||||
<string name="clipboard_password_toast_text">密碼已複製到剪貼簿, 你有 %d 秒的時間將其貼上到其他地方.</string>
|
||||
<string name="clone">從伺服器 Clone</string>
|
||||
<string name="clone_fragment_text">歡迎使用 Password Store 你可以選擇建立新的 Repo 或將你已有的 git repo clone 到你的裝置上</string>
|
||||
<string name="clone_settings">Clone</string>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="accent">#ff7043</color>
|
||||
<color name="background">#eee</color>
|
||||
|
||||
<color name="red_50">#fde0dc</color>
|
||||
<color name="red_100">#f9bdbb</color>
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
<!-- PGPHandler -->
|
||||
<string name="provider_toast_text">No OpenPGP Provider selected!</string>
|
||||
<string name="okc_progress_text">Waiting for OpenKeychain…</string>
|
||||
<string name="clipboard_toast_text">Password copied to clipboard, you have %d seconds to paste it somewhere.</string>
|
||||
<string name="clipboard_password_toast_text">Password copied to clipboard, you have %d seconds to paste it somewhere.</string>
|
||||
<string name="clipboard_username_toast_text">Username copied to clipboard</string>
|
||||
<string name="name_settings_toast_text">Please set your account name in settings whenever you can</string>
|
||||
<string name="account_settings_dialog_text">Please set your OpenKeychain account (email) in the preferences</string>
|
||||
<string name="account_settings_dialog_title">Account name empty!</string>
|
||||
|
@ -97,6 +98,11 @@
|
|||
<string name="action_search">Search</string>
|
||||
<string name="password">Password:</string>
|
||||
<string name="extra_content">Extra content:</string>
|
||||
<string name="username">Username:</string>
|
||||
<string name="edit_password">Edit password</string>
|
||||
<string name="copy_password">Copy password</string>
|
||||
<string name="copy_username">Copy username</string>
|
||||
<string name="share_as_plaintext">Share as plaintext</string>
|
||||
|
||||
<!-- Preferences -->
|
||||
<string name="pref_git_title">Git</string>
|
||||
|
|
Loading…
Reference in a new issue