Second attempt to port our MOTP implementation to an up to date andOTP.
This has been lagging around due to several things. I have also struggled to get my branch in sync with master, so I have built patches and applied them directly to mater here. Let's see if this time I can finally get this pushed and submit a pull request.
This commit is contained in:
parent
fba943c675
commit
01feaa2ecc
37 changed files with 762 additions and 9 deletions
|
@ -210,7 +210,7 @@ public class IntroScreenActivity extends IntroActivity {
|
|||
}
|
||||
});
|
||||
|
||||
selection.setSelection(selectionMapping.indexOfValue(Constants.EncryptionType.PASSWORD));
|
||||
selection.setSelection(selectionMapping.indexOfValue(Constants.EncryptionType.KEYSTORE));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ public class IntroScreenActivity extends IntroActivity {
|
|||
passwordInput.addTextChangedListener(textWatcher);
|
||||
passwordConfirm.addTextChangedListener(textWatcher);
|
||||
|
||||
selection.setSelection(selectionMapping.indexOfValue(Constants.AuthMethod.PASSWORD));
|
||||
selection.setSelection(selectionMapping.indexOfValue(Constants.AuthMethod.NONE));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
|
|
@ -40,11 +40,12 @@ import java.util.Objects;
|
|||
|
||||
public class Entry {
|
||||
public enum OTPType {
|
||||
TOTP, HOTP, STEAM
|
||||
TOTP, HOTP, MOTP, STEAM
|
||||
}
|
||||
|
||||
private static final OTPType DEFAULT_TYPE = OTPType.TOTP;
|
||||
private static final int DEFAULT_PERIOD = 30;
|
||||
private static final String MOTP_NO_PIN_CODE = "PINREQ";
|
||||
|
||||
private static final String JSON_SECRET = "secret";
|
||||
private static final String JSON_ISSUER = "issuer";
|
||||
|
@ -79,6 +80,7 @@ public class Entry {
|
|||
public static final int COLOR_RED = 1;
|
||||
private static final int EXPIRY_TIME = 8;
|
||||
private int color = COLOR_DEFAULT;
|
||||
private String pin = "";
|
||||
|
||||
public Entry(){}
|
||||
|
||||
|
@ -106,6 +108,16 @@ public class Entry {
|
|||
setThumbnailFromIssuer(issuer);
|
||||
}
|
||||
|
||||
public Entry(OTPType type, String secret, String issuer, String label, List<String> tags) {
|
||||
this.type = type;
|
||||
this.secret = secret.getBytes();
|
||||
this.issuer = issuer;
|
||||
this.label = label;
|
||||
this.tags = tags;
|
||||
this.period = TokenCalculator.TOTP_DEFAULT_PERIOD;
|
||||
setThumbnailFromIssuer(issuer);
|
||||
}
|
||||
|
||||
public Entry(String contents) throws Exception {
|
||||
contents = contents.replaceFirst("otpauth", "http");
|
||||
Uri uri = Uri.parse(contents);
|
||||
|
@ -122,6 +134,9 @@ public class Entry {
|
|||
case "hotp":
|
||||
type = OTPType.HOTP;
|
||||
break;
|
||||
case "motp":
|
||||
type = OTPType.MOTP;
|
||||
break;
|
||||
case "steam":
|
||||
type = OTPType.STEAM;
|
||||
break;
|
||||
|
@ -155,7 +170,11 @@ public class Entry {
|
|||
|
||||
this.issuer = issuer;
|
||||
this.label = label;
|
||||
this.secret = new Base32().decode(secret.toUpperCase());
|
||||
if(type == OTPType.MOTP) {
|
||||
this.secret = secret.getBytes();
|
||||
}else{
|
||||
this.secret = new Base32().decode(secret.toUpperCase());
|
||||
}
|
||||
|
||||
if (digits != null) {
|
||||
this.digits = Integer.parseInt(digits);
|
||||
|
@ -323,7 +342,7 @@ public class Entry {
|
|||
}
|
||||
|
||||
public boolean isTimeBased() {
|
||||
return type == OTPType.TOTP || type == OTPType.STEAM;
|
||||
return type == OTPType.TOTP || type == OTPType.STEAM || type == OTPType.MOTP;
|
||||
}
|
||||
|
||||
public boolean isCounterBased() { return type == OTPType.HOTP; }
|
||||
|
@ -444,7 +463,19 @@ public class Entry {
|
|||
return currentOTP;
|
||||
}
|
||||
|
||||
public String getPin() {
|
||||
return pin;
|
||||
}
|
||||
|
||||
public void setPin(String pin) {
|
||||
this.pin = pin;
|
||||
}
|
||||
|
||||
public boolean updateOTP() {
|
||||
return updateOTP(false);
|
||||
}
|
||||
|
||||
public boolean updateOTP(boolean updateNow) {
|
||||
if (type == OTPType.TOTP || type == OTPType.STEAM) {
|
||||
long time = System.currentTimeMillis() / 1000;
|
||||
long counter = time / this.getPeriod();
|
||||
|
@ -465,6 +496,22 @@ public class Entry {
|
|||
} else if (type == OTPType.HOTP) {
|
||||
currentOTP = TokenCalculator.HOTP(secret, counter, digits, algorithm);
|
||||
return true;
|
||||
} else if (type == OTPType.MOTP) {
|
||||
long time = System.currentTimeMillis() / 1000;
|
||||
long counter = time / this.getPeriod();
|
||||
if (counter > last_update || updateNow) {
|
||||
String currentPin = this.getPin();
|
||||
if (currentPin.isEmpty()) {
|
||||
currentOTP = MOTP_NO_PIN_CODE;
|
||||
} else {
|
||||
currentOTP = TokenCalculator.MOTP(currentPin, new String(this.secret));
|
||||
}
|
||||
last_update = counter;
|
||||
setColor(COLOR_DEFAULT);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ public class ManualEntryDialog {
|
|||
final LinearLayout periodLayout = inputView.findViewById(R.id.manual_layout_period);
|
||||
final Spinner algorithmInput = inputView.findViewById(R.id.manual_algorithm);
|
||||
final Button tagsInput = inputView.findViewById(R.id.manual_tags);
|
||||
final Button expandButton = inputView.findViewById(R.id.dialog_expand_button);
|
||||
|
||||
final ArrayAdapter<TokenCalculator.HashAlgorithm> algorithmAdapter = new ArrayAdapter<>(callingActivity, android.R.layout.simple_expandable_list_item_1, TokenCalculator.HashAlgorithm.values());
|
||||
final ArrayAdapter<Entry.OTPType> typeAdapter = new ArrayAdapter<>(callingActivity, android.R.layout.simple_expandable_list_item_1, Entry.OTPType.values());
|
||||
|
@ -100,6 +101,7 @@ public class ManualEntryDialog {
|
|||
if (type == Entry.OTPType.STEAM) {
|
||||
counterLayout.setVisibility(View.GONE);
|
||||
periodLayout.setVisibility(View.VISIBLE);
|
||||
expandButton.setVisibility(View.VISIBLE);
|
||||
|
||||
digitsInput.setText(String.format(Locale.US, "%d", TokenCalculator.STEAM_DEFAULT_DIGITS));
|
||||
periodInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_PERIOD));
|
||||
|
@ -111,6 +113,7 @@ public class ManualEntryDialog {
|
|||
} else if (type == Entry.OTPType.TOTP) {
|
||||
counterLayout.setVisibility(View.GONE);
|
||||
periodLayout.setVisibility(View.VISIBLE);
|
||||
expandButton.setVisibility(View.VISIBLE);
|
||||
|
||||
digitsInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_DIGITS));
|
||||
digitsInput.setEnabled(isNewEntry);
|
||||
|
@ -119,11 +122,19 @@ public class ManualEntryDialog {
|
|||
} else if (type == Entry.OTPType.HOTP) {
|
||||
counterLayout.setVisibility(View.VISIBLE);
|
||||
periodLayout.setVisibility(View.GONE);
|
||||
expandButton.setVisibility(View.VISIBLE);
|
||||
|
||||
digitsInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_DIGITS));
|
||||
digitsInput.setEnabled(isNewEntry);
|
||||
periodInput.setEnabled(isNewEntry);
|
||||
algorithmInput.setEnabled(isNewEntry);
|
||||
}else if (type == Entry.OTPType.MOTP) {
|
||||
counterLayout.setVisibility(View.GONE);
|
||||
periodLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
digitsInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_DIGITS));
|
||||
expandButton.setVisibility(View.GONE);
|
||||
algorithmInput.setEnabled(isNewEntry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,8 +174,6 @@ public class ManualEntryDialog {
|
|||
}
|
||||
});
|
||||
|
||||
final Button expandButton = inputView.findViewById(R.id.dialog_expand_button);
|
||||
|
||||
// Dirty fix for the compound drawable to avoid crashes on KitKat
|
||||
expandButton.setCompoundDrawablesWithIntrinsicBounds(null, null, callingActivity.getResources().getDrawable(R.drawable.ic_arrow_down_accent), null);
|
||||
|
||||
|
|
515
app/src/main/java/org/shadowice/flocke/andotp/Utilities/MD5.java
Normal file
515
app/src/main/java/org/shadowice/flocke/andotp/Utilities/MD5.java
Normal file
|
@ -0,0 +1,515 @@
|
|||
/*
|
||||
* $Header: /u/users20/santtu/src/java/MD5/RCS/MD5.java,v 1.5 1996/12/12 10:47:02 santtu Exp $
|
||||
*
|
||||
* MD5 in Java JDK Beta-2
|
||||
* written Santeri Paavolainen, Helsinki Finland 1996
|
||||
* (c) Santeri Paavolainen, Helsinki Finland 1996
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* See http://www.cs.hut.fi/~santtu/java/ for more information on this
|
||||
* class.
|
||||
*
|
||||
* This is rather straight re-implementation of the reference implementation
|
||||
* given in RFC1321 by RSA.
|
||||
*
|
||||
* Passes MD5 test suite as defined in RFC1321.
|
||||
*
|
||||
*
|
||||
* This Java class has been derived from the RSA Data Security, Inc. MD5
|
||||
* Message-Digest Algorithm and its reference implementation.
|
||||
*
|
||||
*
|
||||
* Revision 1.6 minor changes for j2me, 2003, Matthias Straub
|
||||
*
|
||||
* $Log: MD5.java,v $
|
||||
* Revision 1.5 1996/12/12 10:47:02 santtu
|
||||
* Changed GPL to LGPL
|
||||
*
|
||||
* Revision 1.4 1996/12/12 10:30:02 santtu
|
||||
* Some typos, State -> MD5State etc.
|
||||
*
|
||||
* Revision 1.3 1996/04/15 07:28:09 santtu
|
||||
* Added GPL statemets, and RSA derivate stametemetsnnts.
|
||||
*
|
||||
* Revision 1.2 1996/03/04 08:05:48 santtu
|
||||
* Added offsets to Update method
|
||||
*
|
||||
* Revision 1.1 1996/01/07 20:51:59 santtu
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains internal state of the MD5 class
|
||||
*/
|
||||
package org.shadowice.flocke.andotp.Utilities;
|
||||
|
||||
class MD5State {
|
||||
/**
|
||||
* 128-byte state
|
||||
*/
|
||||
int state[];
|
||||
|
||||
/**
|
||||
* 64-bit character count (could be true Java long?)
|
||||
*/
|
||||
int count[];
|
||||
|
||||
/**
|
||||
* 64-byte buffer (512 bits) for storing to-be-hashed characters
|
||||
*/
|
||||
byte buffer[];
|
||||
|
||||
public MD5State() {
|
||||
buffer = new byte[64];
|
||||
count = new int[2];
|
||||
state = new int[4];
|
||||
|
||||
state[0] = 0x67452301;
|
||||
state[1] = 0xefcdab89;
|
||||
state[2] = 0x98badcfe;
|
||||
state[3] = 0x10325476;
|
||||
|
||||
count[0] = count[1] = 0;
|
||||
}
|
||||
|
||||
/** Create this State as a copy of another state */
|
||||
public MD5State (MD5State from) {
|
||||
this();
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < buffer.length; i++)
|
||||
this.buffer[i] = from.buffer[i];
|
||||
|
||||
for (i = 0; i < state.length; i++)
|
||||
this.state[i] = from.state[i];
|
||||
|
||||
for (i = 0; i < count.length; i++)
|
||||
this.count[i] = from.count[i];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of RSA's MD5 hash generator
|
||||
*
|
||||
* @version $Revision: 1.5 $
|
||||
* @author Santeri Paavolainen <sjpaavol@cc.helsinki.fi>
|
||||
*/
|
||||
|
||||
public class MD5 {
|
||||
/**
|
||||
* MD5 state
|
||||
*/
|
||||
MD5State state;
|
||||
|
||||
/**
|
||||
* If Final() has been called, finals is set to the current finals
|
||||
* state. Any Update() causes this to be set to null.
|
||||
*/
|
||||
MD5State finals;
|
||||
|
||||
/**
|
||||
* Padding for Final()
|
||||
*/
|
||||
static byte padding[] = {
|
||||
(byte) 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize MD5 internal state (object can be reused just by
|
||||
* calling Init() after every Final()
|
||||
*/
|
||||
public synchronized void Init () {
|
||||
state = new MD5State();
|
||||
finals = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
public MD5 () {
|
||||
this.Init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize class, and update hash with ob.toString()
|
||||
*
|
||||
* @param ob Object, ob.toString() is used to update hash
|
||||
* after initialization
|
||||
*/
|
||||
public MD5 (Object ob) {
|
||||
this();
|
||||
Update(ob.toString());
|
||||
}
|
||||
|
||||
private int rotate_left (int x, int n) {
|
||||
return (x << n) | (x >>> (32 - n));
|
||||
}
|
||||
|
||||
/* I wonder how many loops and hoops you'll have to go through to
|
||||
get unsigned add for longs in java */
|
||||
|
||||
private int uadd (int a, int b) {
|
||||
long aa, bb;
|
||||
aa = ((long) a) & 0xffffffffL;
|
||||
bb = ((long) b) & 0xffffffffL;
|
||||
|
||||
aa += bb;
|
||||
|
||||
return (int) (aa & 0xffffffffL);
|
||||
}
|
||||
|
||||
private int uadd (int a, int b, int c) {
|
||||
return uadd(uadd(a, b), c);
|
||||
}
|
||||
|
||||
private int uadd (int a, int b, int c, int d) {
|
||||
return uadd(uadd(a, b, c), d);
|
||||
}
|
||||
|
||||
private int FF (int a, int b, int c, int d, int x, int s, int ac) {
|
||||
a = uadd(a, ((b & c) | (~b & d)), x, ac);
|
||||
return uadd(rotate_left(a, s), b);
|
||||
}
|
||||
|
||||
private int GG (int a, int b, int c, int d, int x, int s, int ac) {
|
||||
a = uadd(a, ((b & d) | (c & ~d)), x, ac);
|
||||
return uadd(rotate_left(a, s), b);
|
||||
}
|
||||
|
||||
private int HH (int a, int b, int c, int d, int x, int s, int ac) {
|
||||
a = uadd(a, (b ^ c ^ d), x, ac);
|
||||
return uadd(rotate_left(a, s) , b);
|
||||
}
|
||||
|
||||
private int II (int a, int b, int c, int d, int x, int s, int ac) {
|
||||
a = uadd(a, (c ^ (b | ~d)), x, ac);
|
||||
return uadd(rotate_left(a, s), b);
|
||||
}
|
||||
|
||||
private int[] Decode (byte buffer[], int len, int shift) {
|
||||
int out[];
|
||||
int i, j;
|
||||
|
||||
out = new int[16];
|
||||
|
||||
for (i = j = 0; j < len; i++, j += 4) {
|
||||
out[i] = ((int) (buffer[j + shift] & 0xff)) |
|
||||
(((int) (buffer[j + 1 + shift] & 0xff)) << 8) |
|
||||
(((int) (buffer[j + 2 + shift] & 0xff)) << 16) |
|
||||
(((int) (buffer[j + 3 + shift] & 0xff)) << 24);
|
||||
|
||||
/* System.out.println("out[" + i + "] = \t" +
|
||||
((int) buffer[j + 0 + shift] & 0xff) + "\t|\t" +
|
||||
((int) buffer[j + 1 + shift] & 0xff) + "\t|\t" +
|
||||
((int) buffer[j + 2 + shift] & 0xff) + "\t|\t" +
|
||||
((int) buffer[j + 3 + shift] & 0xff));*/
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private void Transform (MD5State state, byte buffer[], int shift) {
|
||||
int
|
||||
a = state.state[0],
|
||||
b = state.state[1],
|
||||
c = state.state[2],
|
||||
d = state.state[3],
|
||||
x[];
|
||||
|
||||
x = Decode(buffer, 64, shift);
|
||||
|
||||
/* Round 1 */
|
||||
a = FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
|
||||
d = FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
|
||||
c = FF (c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
|
||||
b = FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
|
||||
a = FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
|
||||
d = FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
|
||||
c = FF (c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
|
||||
b = FF (b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
|
||||
a = FF (a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
|
||||
d = FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
|
||||
c = FF (c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
|
||||
b = FF (b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
|
||||
a = FF (a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
|
||||
d = FF (d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
|
||||
c = FF (c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
|
||||
b = FF (b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
a = GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
|
||||
d = GG (d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
|
||||
c = GG (c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
|
||||
b = GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
|
||||
a = GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
|
||||
d = GG (d, a, b, c, x[10], 9, 0x2441453); /* 22 */
|
||||
c = GG (c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
|
||||
b = GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
|
||||
a = GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
|
||||
d = GG (d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
|
||||
c = GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
|
||||
b = GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
|
||||
a = GG (a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
|
||||
d = GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
|
||||
c = GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
|
||||
b = GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
a = HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
|
||||
d = HH (d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
|
||||
c = HH (c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
|
||||
b = HH (b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
|
||||
a = HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
|
||||
d = HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
|
||||
c = HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
|
||||
b = HH (b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
|
||||
a = HH (a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
|
||||
d = HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
|
||||
c = HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
|
||||
b = HH (b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
|
||||
a = HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
|
||||
d = HH (d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
|
||||
c = HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
|
||||
b = HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
a = II (a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
|
||||
d = II (d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
|
||||
c = II (c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
|
||||
b = II (b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
|
||||
a = II (a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
|
||||
d = II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
|
||||
c = II (c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
|
||||
b = II (b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
|
||||
a = II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
|
||||
d = II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
|
||||
c = II (c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
|
||||
b = II (b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
|
||||
a = II (a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
|
||||
d = II (d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
|
||||
c = II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
|
||||
b = II (b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
|
||||
|
||||
state.state[0] += a;
|
||||
state.state[1] += b;
|
||||
state.state[2] += c;
|
||||
state.state[3] += d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates hash with the bytebuffer given (using at maximum length bytes from
|
||||
* that buffer)
|
||||
*
|
||||
* @param stat Which state is updated
|
||||
* @param buffer Array of bytes to be hashed
|
||||
* @param offset Offset to buffer array
|
||||
* @param length Use at maximum `length' bytes (absolute
|
||||
* maximum is buffer.length)
|
||||
*/
|
||||
public void Update (MD5State stat, byte buffer[], int offset, int length) {
|
||||
int index, partlen, i, start;
|
||||
|
||||
/* System.out.print("Offset = " + offset + "\tLength = " + length + "\t");
|
||||
System.out.print("Buffer = ");
|
||||
for (i = 0; i < buffer.length; i++)
|
||||
System.out.print((int) (buffer[i] & 0xff) + " ");
|
||||
System.out.print("\n");*/
|
||||
|
||||
finals = null;
|
||||
|
||||
/* Length can be told to be shorter, but not inter */
|
||||
if ((length - offset)> buffer.length)
|
||||
length = buffer.length - offset;
|
||||
|
||||
/* compute number of bytes mod 64 */
|
||||
index = (int) (stat.count[0] >>> 3) & 0x3f;
|
||||
|
||||
if ((stat.count[0] += (length << 3)) <
|
||||
(length << 3))
|
||||
stat.count[1]++;
|
||||
|
||||
stat.count[1] += length >>> 29;
|
||||
|
||||
partlen = 64 - index;
|
||||
|
||||
if (length >= partlen) {
|
||||
for (i = 0; i < partlen; i++)
|
||||
stat.buffer[i + index] = buffer[i + offset];
|
||||
|
||||
Transform(stat, stat.buffer, 0);
|
||||
|
||||
for (i = partlen; (i + 63) < length; i+= 64)
|
||||
Transform(stat, buffer, i);
|
||||
|
||||
index = 0;
|
||||
} else
|
||||
i = 0;
|
||||
|
||||
/* buffer remaining input */
|
||||
if (i < length) {
|
||||
start = i;
|
||||
for (; i < length; i++)
|
||||
stat.buffer[index + i - start] = buffer[i + offset];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update()s for other datatypes than byte[] also. Update(byte[], int)
|
||||
* is only the main driver.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plain update, updates this object
|
||||
*/
|
||||
|
||||
public void Update (byte buffer[], int offset, int length) {
|
||||
Update(this.state, buffer, offset, length);
|
||||
}
|
||||
|
||||
public void Update (byte buffer[], int length) {
|
||||
Update(this.state, buffer, 0, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates hash with given array of bytes
|
||||
*
|
||||
* @param buffer Array of bytes to use for updating the hash
|
||||
*/
|
||||
public void Update (byte buffer[]) {
|
||||
Update(buffer, 0, buffer.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates hash with a single byte
|
||||
*
|
||||
* @param b Single byte to update the hash
|
||||
*/
|
||||
public void Update (byte b) {
|
||||
byte buffer[] = new byte[1];
|
||||
buffer[0] = b;
|
||||
|
||||
Update(buffer, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update buffer with given string.
|
||||
*
|
||||
* @param s String to be update to hash (is used as
|
||||
* s.getBytes())
|
||||
*/
|
||||
public void Update (String s) {
|
||||
byte chars[];
|
||||
|
||||
chars = new byte[s.length()];
|
||||
chars=s.getBytes();
|
||||
|
||||
Update(chars, chars.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update buffer with a single integer (only & 0xff part is used,
|
||||
* as a byte)
|
||||
*
|
||||
* @param i Integer value, which is then converted to
|
||||
* byte as i & 0xff
|
||||
*/
|
||||
|
||||
public void Update (int i) {
|
||||
Update((byte) (i & 0xff));
|
||||
}
|
||||
|
||||
private byte[] Encode (int input[], int len) {
|
||||
int i, j;
|
||||
byte out[];
|
||||
|
||||
out = new byte[len];
|
||||
|
||||
for (i = j = 0; j < len; i++, j += 4) {
|
||||
out[j] = (byte) (input[i] & 0xff);
|
||||
out[j + 1] = (byte) ((input[i] >>> 8) & 0xff);
|
||||
out[j + 2] = (byte) ((input[i] >>> 16) & 0xff);
|
||||
out[j + 3] = (byte) ((input[i] >>> 24) & 0xff);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of bytes (16 bytes) representing hash as of the
|
||||
* current state of this object. Note: getting a hash does not
|
||||
* invalidate the hash object, it only creates a copy of the real
|
||||
* state which is finalized.
|
||||
*
|
||||
* @return Array of 16 bytes, the hash of all updated bytes
|
||||
*/
|
||||
public synchronized byte[] Final () {
|
||||
byte bits[];
|
||||
int index, padlen;
|
||||
MD5State fin;
|
||||
|
||||
if (finals == null) {
|
||||
fin = new MD5State(state);
|
||||
|
||||
bits = Encode(fin.count, 8);
|
||||
|
||||
index = (int) ((fin.count[0] >>> 3) & 0x3f);
|
||||
padlen = (index < 56) ? (56 - index) : (120 - index);
|
||||
|
||||
Update(fin, padding, 0, padlen);
|
||||
/**/
|
||||
Update(fin, bits, 0, 8);
|
||||
|
||||
/* Update() sets finalds to null */
|
||||
finals = fin;
|
||||
}
|
||||
|
||||
return Encode(finals.state, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns array of bytes into string representing each byte as
|
||||
* unsigned hex number.
|
||||
*
|
||||
* @param hash Array of bytes to convert to hex-string
|
||||
* @return Generated hex string
|
||||
*/
|
||||
public static String asHex (byte hash[]) {
|
||||
StringBuffer buf = new StringBuffer(hash.length * 2);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < hash.length; i++) {
|
||||
if (((int) hash[i] & 0xff) < 0x10)
|
||||
buf.append("0");
|
||||
|
||||
buf.append(Long.toString((int) hash[i] & 0xff, 16));
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 32-character hex representation of this objects hash
|
||||
*
|
||||
* @return String of this object's hash
|
||||
*/
|
||||
public String asHex () {
|
||||
return asHex(this.Final());
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ package org.shadowice.flocke.andotp.Utilities;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
@ -115,4 +116,15 @@ public class TokenCalculator {
|
|||
|
||||
return r;
|
||||
}
|
||||
|
||||
public static String MOTP(String PIN, String secret)
|
||||
{
|
||||
Date dateNow = new Date();
|
||||
String epoch = "" + (dateNow.getTime());
|
||||
epoch = epoch.substring(0, epoch.length() - 4);
|
||||
String otp = epoch + secret + PIN;
|
||||
MD5 hash = new MD5(otp);
|
||||
otp = hash.asHex().substring(0, 6);
|
||||
return otp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,10 +48,17 @@ public class UIHelper {
|
|||
.show();
|
||||
}
|
||||
|
||||
public static void showKeyboard(Context context, View view) {
|
||||
public static void showKeyboard(Context context, View view){
|
||||
showKeyboard(context,view,false);
|
||||
}
|
||||
|
||||
public static void showKeyboard(Context context, View view, Boolean showForced) {
|
||||
if (view != null) {
|
||||
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.showSoftInput(view, 0);
|
||||
if(showForced)
|
||||
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
|
||||
else
|
||||
imm.showSoftInput(view, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,11 +36,14 @@ import android.text.Editable;
|
|||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.method.PasswordTransformationMethod;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
|
@ -66,6 +69,7 @@ import org.shadowice.flocke.andotp.Utilities.EncryptionHelper;
|
|||
import org.shadowice.flocke.andotp.Utilities.EntryThumbnail;
|
||||
import org.shadowice.flocke.andotp.Utilities.Settings;
|
||||
import org.shadowice.flocke.andotp.Utilities.Tools;
|
||||
import org.shadowice.flocke.andotp.Utilities.UIHelper;
|
||||
import org.shadowice.flocke.andotp.View.ItemTouchHelper.ItemTouchHelperAdapter;
|
||||
|
||||
import java.text.Collator;
|
||||
|
@ -97,6 +101,8 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
private TagsAdapter tagsFilterAdapter;
|
||||
private Settings settings;
|
||||
|
||||
private static final int ESTABLISH_PIN_MENU_INDEX = 4;
|
||||
|
||||
public EntriesCardAdapter(Context context, TagsAdapter tagsFilterAdapter) {
|
||||
this.context = context;
|
||||
this.tagsFilterAdapter = tagsFilterAdapter;
|
||||
|
@ -355,6 +361,14 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
public void onCounterLongPressed(int position) {
|
||||
setCounter(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClickListener(int position) {
|
||||
final Entry entry = displayedEntries.get(position);
|
||||
if(entry.getType() == Entry.OTPType.MOTP && entry.getPin().isEmpty()){
|
||||
establishPIN(position);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return viewHolder;
|
||||
|
@ -620,6 +634,52 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
alert.show();
|
||||
}
|
||||
|
||||
public void establishPIN(final int pos) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
|
||||
int marginSmall = context.getResources().getDimensionPixelSize(R.dimen.activity_margin_small);
|
||||
int marginMedium = context.getResources().getDimensionPixelSize(R.dimen.activity_margin_medium);
|
||||
|
||||
final EditText input = new EditText(context);
|
||||
input.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
input.setRawInputType(InputType.TYPE_NUMBER_VARIATION_PASSWORD | InputType.TYPE_CLASS_NUMBER);
|
||||
input.setText(displayedEntries.get(pos).getPin());
|
||||
input.setSingleLine();
|
||||
input.requestFocus();
|
||||
input.setTransformationMethod(new PasswordTransformationMethod());
|
||||
UIHelper.showKeyboard(context,input,true);
|
||||
|
||||
FrameLayout container = new FrameLayout(context);
|
||||
container.setPaddingRelative(marginMedium, marginSmall, marginMedium, 0);
|
||||
container.addView(input);
|
||||
|
||||
builder.setTitle(R.string.dialog_title_pin)
|
||||
.setCancelable(false)
|
||||
.setView(container)
|
||||
.setPositiveButton(R.string.button_accept, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
int realIndex = getRealIndex(pos);
|
||||
String newPin = input.getEditableText().toString();
|
||||
|
||||
displayedEntries.get(pos).setPin(newPin);
|
||||
Entry e = entries.get(realIndex);
|
||||
e.setPin(newPin);
|
||||
e.updateOTP(true);
|
||||
notifyDataSetChanged();
|
||||
UIHelper.hideKeyboard(context,input);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
UIHelper.hideKeyboard(context,input);
|
||||
}
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
|
||||
public void removeItem(final int pos) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
|
||||
|
@ -682,6 +742,11 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
MenuInflater inflate = popup.getMenuInflater();
|
||||
inflate.inflate(R.menu.menu_popup, popup.getMenu());
|
||||
|
||||
if (displayedEntries.get(pos).getType() == Entry.OTPType.MOTP){
|
||||
MenuItem item = popup.getMenu().getItem(ESTABLISH_PIN_MENU_INDEX);
|
||||
item.setVisible(true);
|
||||
}
|
||||
|
||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
|
@ -693,6 +758,9 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
|||
} else if(id == R.id.menu_popup_changeImage) {
|
||||
changeThumbnail(pos);
|
||||
return true;
|
||||
} else if (id == R.id.menu_popup_establishPin) {
|
||||
establishPIN(pos);
|
||||
return true;
|
||||
} else if (id == R.id.menu_popup_remove) {
|
||||
removeItem(pos);
|
||||
return true;
|
||||
|
|
|
@ -154,6 +154,14 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
}
|
||||
});
|
||||
|
||||
itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (callback != null)
|
||||
callback.onItemClickListener(getAdapterPosition());
|
||||
}
|
||||
});
|
||||
|
||||
setTapToReveal(tapToReveal);
|
||||
}
|
||||
|
||||
|
@ -328,6 +336,7 @@ public class EntryViewHolder extends RecyclerView.ViewHolder
|
|||
|
||||
void onCounterClicked(int position);
|
||||
void onCounterLongPressed(int position);
|
||||
void onItemClickListener(int position);
|
||||
}
|
||||
/**
|
||||
* Updates the color of OTP to red (if expiring) or default color (if new OTP)
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/activity_margin_xxsmall"
|
||||
android:layout_marginBottom="@dimen/activity_margin_xxsmall"
|
||||
android:clickable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
app:contentPadding="0dp"
|
||||
style="?attr/cardStyle">
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/activity_margin_xsmall"
|
||||
android:layout_marginBottom="@dimen/activity_margin_xsmall"
|
||||
android:clickable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
app:contentPadding="0dp"
|
||||
style="?attr/cardStyle">
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
android:layout_marginTop="@dimen/activity_margin_xsmall"
|
||||
android:layout_marginBottom="@dimen/activity_margin_xsmall"
|
||||
app:contentPadding="0dp"
|
||||
android:clickable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
style="?attr/cardStyle">
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
android:id="@+id/menu_popup_show_qr_code"
|
||||
android:title="@string/menu_popup_show_qr_code" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_popup_establishPin"
|
||||
android:title="@string/menu_popup_establish_pin"
|
||||
android:visible="false"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_popup_remove"
|
||||
android:title="@string/menu_popup_remove" />
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">كافة العلامات</string>
|
||||
<string name="button_no_tags">بدون علامات</string>
|
||||
<string name="button_qr_from_image">رمز كيو آر مِن صورة</string>
|
||||
<string name="button_accept">اقبل</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d ثا</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">تغيير الصورة</string>
|
||||
<string name="menu_popup_remove">حذف</string>
|
||||
<string name="menu_popup_show_qr_code">Show QR Code</string>
|
||||
<string name="menu_popup_establish_pin">أدخل رمز PIN</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">أخفقت المصادقة، الرجاء إعادة المحاولة !</string>
|
||||
<string name="toast_auth_failed_fatal">أخفقت عملية المصادقة، جارٍ إغلاق التطبيق!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_android21_depreaction">Deprecation notice</string>
|
||||
<string name="dialog_title_enter_password">أدخل كلمة المرور</string>
|
||||
<string name="dialog_title_pin">دبوس</string>
|
||||
<string name="dialog_label_enter_password">أدخل كلمة المرور</string>
|
||||
<string name="dialog_label_confirm_password">تأكيد كلمة المرور</string>
|
||||
<string name="dialog_msg_auth">الرجاء إدخال بيانات الإعتماد الخاصة بجهازك لتشغيل التطبيق.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Всички маркери</string>
|
||||
<string name="button_no_tags">Няма маркери</string>
|
||||
<string name="button_qr_from_image">QR код от изображение</string>
|
||||
<string name="button_accept">приемам</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d сек</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Промяна на изображението</string>
|
||||
<string name="menu_popup_remove">Премахване</string>
|
||||
<string name="menu_popup_show_qr_code">Показване на QR кода</string>
|
||||
<string name="menu_popup_establish_pin">Въведете ПИН код</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Неуспешно удостоверяване. Моля, опитайте отново!</string>
|
||||
<string name="toast_auth_failed_fatal">Неуспешно удостоверяване, затваряне на andOTP!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR код</string>
|
||||
<string name="dialog_title_android21_depreaction">Остаряло известие</string>
|
||||
<string name="dialog_title_enter_password">Въведете парола</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Въведете парола</string>
|
||||
<string name="dialog_label_confirm_password">Потвърдете паролата</string>
|
||||
<string name="dialog_msg_auth">Моля, въведете идентификационните данни на устройството си, за да стартирате andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Totes les etiquetes</string>
|
||||
<string name="button_no_tags">Sense etiquetes</string>
|
||||
<string name="button_qr_from_image">QR code from image</string>
|
||||
<string name="button_accept">Acceptar</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Canvia la imatge</string>
|
||||
<string name="menu_popup_remove">Suprimeix</string>
|
||||
<string name="menu_popup_show_qr_code">Show QR Code</string>
|
||||
<string name="menu_popup_establish_pin">Introduir PIN</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Error d\'autenticació. Torneu-ho a intentar!</string>
|
||||
<string name="toast_auth_failed_fatal">L\'autenticació ha fallat, andOTP es tancarà!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_android21_depreaction">Deprecation notice</string>
|
||||
<string name="dialog_title_enter_password">Introduïu la contrasenya</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Introduïu la contrasenya</string>
|
||||
<string name="dialog_label_confirm_password">Confirmeu la contrasenya</string>
|
||||
<string name="dialog_msg_auth">Per favor, introduïu les vostres credencials per a iniciar andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Všechny štítky</string>
|
||||
<string name="button_no_tags">Bez štítku</string>
|
||||
<string name="button_qr_from_image">QR kód z obrázku</string>
|
||||
<string name="button_accept">Přijmout</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Změnit obrázek</string>
|
||||
<string name="menu_popup_remove">Smazat</string>
|
||||
<string name="menu_popup_show_qr_code">Ukaž QR kód</string>
|
||||
<string name="menu_popup_establish_pin">Zadejte PIN</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Chyba ověření, zkuste to prosím znovu!</string>
|
||||
<string name="toast_auth_failed_fatal">Ověření se nezdařilo, zavírám andOTP!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR kód</string>
|
||||
<string name="dialog_title_android21_depreaction">Oznámení o ukončení podpory</string>
|
||||
<string name="dialog_title_enter_password">Zadejte heslo</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Zadejte heslo</string>
|
||||
<string name="dialog_label_confirm_password">Potvrďte heslo</string>
|
||||
<string name="dialog_msg_auth">Prosím zadejte heslo zařízení ke spuštění andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Alle Marker</string>
|
||||
<string name="button_no_tags">Keine Marker</string>
|
||||
<string name="button_qr_from_image">QR-Code aus Bild</string>
|
||||
<string name="button_accept">Akzeptiere</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Bild ändern</string>
|
||||
<string name="menu_popup_remove">Entfernen</string>
|
||||
<string name="menu_popup_show_qr_code">Zeige QR-Code</string>
|
||||
<string name="menu_popup_establish_pin">PIN einstellen</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Authentifizierung fehlgeschlagen, bitte erneut versuchen!</string>
|
||||
<string name="toast_auth_failed_fatal">Authentifizierung fehlgeschlagen, andOTP wird geschlossen!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR-Code</string>
|
||||
<string name="dialog_title_android21_depreaction">Hinweis</string>
|
||||
<string name="dialog_title_enter_password">Passwort eingeben</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Passwort eingeben</string>
|
||||
<string name="dialog_label_confirm_password">Passwort bestätigen</string>
|
||||
<string name="dialog_msg_auth">Bitte geben Sie die Anmeldeinformationen Ihres Geräts ein, um andOTP zu starten.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Όλες οι ετικέτες</string>
|
||||
<string name="button_no_tags">Χωρίς ετικέτες</string>
|
||||
<string name="button_qr_from_image">Κώδικας QR από εικόνα</string>
|
||||
<string name="button_accept">Αποδοχή</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d\"</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Αλλαγή εικόνας</string>
|
||||
<string name="menu_popup_remove">Διαγραφή</string>
|
||||
<string name="menu_popup_show_qr_code">Show QR Code</string>
|
||||
<string name="menu_popup_establish_pin">Ορίστε το PIN</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Η ταυτοποίηση απέτυχε. Παρακαλώ προσπάθησε ξανά!</string>
|
||||
<string name="toast_auth_failed_fatal">Απέτυχε ο έλεγχος ταυτότητας, κλείνει το andOTP!</string>
|
||||
|
@ -74,6 +76,7 @@
|
|||
<string name="dialog_title_android21_depreaction">Deprecation notice</string>
|
||||
<string name="dialog_title_enter_password">Εισάγετε κωδικό</string>
|
||||
<string name="dialog_label_enter_password">Εισάγετε κωδικό</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_confirm_password">Επιβεβαίωση κωδικού</string>
|
||||
<string name="dialog_msg_auth">Παρακαλούμε εισαγάγετε τα διαπιστευτήριά σας για να ανοίξετε το andOTP.</string>
|
||||
<string name="dialog_msg_confirm_delete">Σίγουρα θέλετε να αφαιρέσετε το λογαριασμό \"%1$s\";</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Todas las etiquetas</string>
|
||||
<string name="button_no_tags">Sin etiquetas</string>
|
||||
<string name="button_qr_from_image">Imagen del código QR</string>
|
||||
<string name="button_accept">Aceptar</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Cambiar imagen</string>
|
||||
<string name="menu_popup_remove">Eliminar</string>
|
||||
<string name="menu_popup_show_qr_code">Mostrar código QR</string>
|
||||
<string name="menu_popup_establish_pin">Introducir pin</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">La autentificación ha fallado, por favor inténtelo otra vez!</string>
|
||||
<string name="toast_auth_failed_fatal">La autenticación ha fallado, cerrando andOTP!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">Código QR</string>
|
||||
<string name="dialog_title_android21_depreaction">Aviso de deprecación</string>
|
||||
<string name="dialog_title_enter_password">Introduzca la contraseña</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Introduzca la contraseña</string>
|
||||
<string name="dialog_label_confirm_password">Confirmar contraseña</string>
|
||||
<string name="dialog_msg_auth">Por favor, introduce los credenciales del dispositivo para iniciar andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">همه تگها</string>
|
||||
<string name="button_no_tags">بدون تگ</string>
|
||||
<string name="button_qr_from_image">کد QR از تصویر</string>
|
||||
<string name="button_accept">قبول کنید</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d ثانیه</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">تغییر تصویر</string>
|
||||
<string name="menu_popup_remove">حذف</string>
|
||||
<string name="menu_popup_show_qr_code">نمایش کد QR</string>
|
||||
<string name="menu_popup_establish_pin">پین را تنظیم کنید</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">احراز هویت ناموفق بود، لطفا دوباره تلاش کنید!</string>
|
||||
<string name="toast_auth_failed_fatal">احراز هویت ناموفق بود، در حال بستن andOTP!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">کد QR</string>
|
||||
<string name="dialog_title_android21_depreaction">اخطار استهلاک</string>
|
||||
<string name="dialog_title_enter_password">گذرواژه را وارد کنید</string>
|
||||
<string name="dialog_title_pin">پین</string>
|
||||
<string name="dialog_label_enter_password">گذرواژه را وارد کنید</string>
|
||||
<string name="dialog_label_confirm_password">تایید گذرواژه</string>
|
||||
<string name="dialog_msg_auth">برای شروع andOTP لطفا اعتبارنامه دستگاه خود را وارد کنید.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Tous les tags</string>
|
||||
<string name="button_no_tags">Aucun tag</string>
|
||||
<string name="button_qr_from_image">QR-code à partir d\'une image</string>
|
||||
<string name="button_accept">Accepter</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Modifier l\'image</string>
|
||||
<string name="menu_popup_remove">Supprimer</string>
|
||||
<string name="menu_popup_show_qr_code">Montrer le QR Code</string>
|
||||
<string name="menu_popup_establish_pin">Définir le code PIN</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Échec d\'authentification, veuillez réessayer !</string>
|
||||
<string name="toast_auth_failed_fatal">Échec d\'authentification, fermeture d\'andOTP !</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_android21_depreaction">Avis d\'obsolescence</string>
|
||||
<string name="dialog_title_enter_password">Saisir le mot de passe</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Saisir le mot de passe</string>
|
||||
<string name="dialog_label_confirm_password">Confirmer le mot de passe</string>
|
||||
<string name="dialog_msg_auth">Veuillez entrer les informations d\'identification du périphérique pour démarrer andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Todas as etiquetas</string>
|
||||
<string name="button_no_tags">Sen etiquetas</string>
|
||||
<string name="button_qr_from_image">Código QR desde imaxe</string>
|
||||
<string name="button_accept">Aceptar</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Cambiar imaxe</string>
|
||||
<string name="menu_popup_remove">Eliminar</string>
|
||||
<string name="menu_popup_show_qr_code">Mostrar código QR</string>
|
||||
<string name="menu_popup_establish_pin">Introducir o pin</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Fallou a autenticación, por favor inténtao de novo!</string>
|
||||
<string name="toast_auth_failed_fatal">Fallou a autenticación, pechando andOTP!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">Código QR</string>
|
||||
<string name="dialog_title_android21_depreaction">Aviso de abandono</string>
|
||||
<string name="dialog_title_enter_password">Introducir contrasinal</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Introducir contrasinal</string>
|
||||
<string name="dialog_label_confirm_password">Confirmar contrasinal</string>
|
||||
<string name="dialog_msg_auth">Introduce as credenciais do dispositivo para iniciar andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">सभी टैग</string>
|
||||
<string name="button_no_tags">कोई टैग नहीं</string>
|
||||
<string name="button_qr_from_image">छवि से क्यूआर कोड</string>
|
||||
<string name="button_accept">स्वीकार करना</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d सेकेंड</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">छवि बदलें</string>
|
||||
<string name="menu_popup_remove">हटाएं</string>
|
||||
<string name="menu_popup_show_qr_code">Show QR Code</string>
|
||||
<string name="menu_popup_establish_pin">पिन सेट करें</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">प्रमाणीकरण असफल| कृपया पुन: प्रयास करें!</string>
|
||||
<string name="toast_auth_failed_fatal">प्रमाणीकरण विफल, समापन andOTP!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_android21_depreaction">Deprecation notice</string>
|
||||
<string name="dialog_title_enter_password">अपना पासवोर्ड डाले</string>
|
||||
<string name="dialog_title_pin">पिन</string>
|
||||
<string name="dialog_label_enter_password">अपना पासवोर्ड डाले</string>
|
||||
<string name="dialog_label_confirm_password">पासवर्ड की पुष्टि करें</string>
|
||||
<string name="dialog_msg_auth">AndOTP शुरू करने के लिए कृपया अपनी यंत्र साख दर्ज करें।</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Összes címke</string>
|
||||
<string name="button_no_tags">Nincs címke</string>
|
||||
<string name="button_qr_from_image">QR-kód képből</string>
|
||||
<string name="button_accept">Elfogad</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d másodperc</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Kép módosítása</string>
|
||||
<string name="menu_popup_remove">Eltávolítás</string>
|
||||
<string name="menu_popup_show_qr_code">Show QR Code</string>
|
||||
<string name="menu_popup_establish_pin">Állítsa be a PIN-kódot</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">A hitelesítés sikertelen, próbálja újra!</string>
|
||||
<string name="toast_auth_failed_fatal">A hitelesítés sikertelen, az andOTP bezárul!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_android21_depreaction">Deprecation notice</string>
|
||||
<string name="dialog_title_enter_password">Jelszó megadása</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Jelszó megadása</string>
|
||||
<string name="dialog_label_confirm_password">Jelszó megerősítése</string>
|
||||
<string name="dialog_msg_auth">Kérjük, adja meg a készülék hitelesítő adatait az andOTP indításához.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Tutti i tag</string>
|
||||
<string name="button_no_tags">Nessun tag</string>
|
||||
<string name="button_qr_from_image">QR code da immagine</string>
|
||||
<string name="button_accept">Accettare</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Cambia Immagine</string>
|
||||
<string name="menu_popup_remove">Rimuovi</string>
|
||||
<string name="menu_popup_show_qr_code">Mostra codice QR</string>
|
||||
<string name="menu_popup_establish_pin">Imposta PIN</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Autenticazione non riuscita, riprova!</string>
|
||||
<string name="toast_auth_failed_fatal">Autenticazione non riuscita, andOTP verrà chiuso!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">Codice QR</string>
|
||||
<string name="dialog_title_android21_depreaction">Avviso di deprecazione</string>
|
||||
<string name="dialog_title_enter_password">Inserisci la password</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Inserisci la password</string>
|
||||
<string name="dialog_label_confirm_password">Conferma la password</string>
|
||||
<string name="dialog_msg_auth">Si prega di inserire le credenziali del dispositivo per avviare andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">すべてのタグ</string>
|
||||
<string name="button_no_tags">タグなし</string>
|
||||
<string name="button_qr_from_image">QR コードを画像からスキャン</string>
|
||||
<string name="button_accept">受け入れる</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d 秒</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">画像を変更</string>
|
||||
<string name="menu_popup_remove">削除</string>
|
||||
<string name="menu_popup_show_qr_code">QR コードを表示</string>
|
||||
<string name="menu_popup_establish_pin">PINを設定</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">認証に失敗しました、もう一度やり直してください!</string>
|
||||
<string name="toast_auth_failed_fatal">認証に失敗しました、 andOTP を終了します!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR コード</string>
|
||||
<string name="dialog_title_android21_depreaction">サポート廃止の通知</string>
|
||||
<string name="dialog_title_enter_password">パスワードを入力</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">パスワードを入力</string>
|
||||
<string name="dialog_label_confirm_password">パスワードの確認</string>
|
||||
<string name="dialog_msg_auth">andOTP を起動するためにデバイス認証情報を入力してください。</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Alle labels</string>
|
||||
<string name="button_no_tags">Geen labels</string>
|
||||
<string name="button_qr_from_image">QR-code van afbeelding</string>
|
||||
<string name="button_accept">Accepteren</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Afbeelding wijzigen</string>
|
||||
<string name="menu_popup_remove">Verwijderen</string>
|
||||
<string name="menu_popup_show_qr_code">Show QR Code</string>
|
||||
<string name="menu_popup_establish_pin">PIN instellen</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Authenticatie mislukt. Probeer opnieuw!</string>
|
||||
<string name="toast_auth_failed_fatal">Verificatie is mislukt, andOTP wordt afgesloten!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_android21_depreaction">Deprecation notice</string>
|
||||
<string name="dialog_title_enter_password">Wachtwoord invoeren</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Wachtwoord invoeren</string>
|
||||
<string name="dialog_label_confirm_password">Wachtwoord bevestigen</string>
|
||||
<string name="dialog_msg_auth">Voer de referenties van uw apparaat in om te beginnen met andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Wszystkie znaczniki</string>
|
||||
<string name="button_no_tags">Brak znaczników</string>
|
||||
<string name="button_qr_from_image">Kod QR z obrazu</string>
|
||||
<string name="button_accept">Zaakceptuj</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Zmień obraz</string>
|
||||
<string name="menu_popup_remove">Usuń</string>
|
||||
<string name="menu_popup_show_qr_code">Pokaż kod QR</string>
|
||||
<string name="menu_popup_establish_pin">Ustaw PIN</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Uwierzytelnianie nie powiodło się, proszę spróbować ponownie</string>
|
||||
<string name="toast_auth_failed_fatal">Uwierzytelnianie nie powiodło się, zamykanie andOTP</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">Kod QR</string>
|
||||
<string name="dialog_title_android21_depreaction">Informacja o wycofaniu</string>
|
||||
<string name="dialog_title_enter_password">Wprowadź hasło</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Wprowadź hasło</string>
|
||||
<string name="dialog_label_confirm_password">Potwierdź hasło</string>
|
||||
<string name="dialog_msg_auth">Podaj swoje dane uwierzytelniające, aby uruchomić andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Todos os marcadores</string>
|
||||
<string name="button_no_tags">Sem marcadores</string>
|
||||
<string name="button_qr_from_image">QR code from image</string>
|
||||
<string name="button_accept">Aceitar</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Alterar imagem</string>
|
||||
<string name="menu_popup_remove">Remover</string>
|
||||
<string name="menu_popup_show_qr_code">Show QR Code</string>
|
||||
<string name="menu_popup_establish_pin">Definir PIN</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Falha na autenticação. Por favor, tente novamente.</string>
|
||||
<string name="toast_auth_failed_fatal">Falha na autenticação, fechando o aplicativo.</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_android21_depreaction">Deprecation notice</string>
|
||||
<string name="dialog_title_enter_password">Digite a senha</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Digite a senha</string>
|
||||
<string name="dialog_label_confirm_password">Confirme a senha</string>
|
||||
<string name="dialog_msg_auth">Por favor, insira credenciais do dispositivo para iniciar andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Все теги</string>
|
||||
<string name="button_no_tags">Нет тегов</string>
|
||||
<string name="button_qr_from_image">QR код из изображения</string>
|
||||
<string name="button_accept">принимать</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d сек.</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Изменить изображение</string>
|
||||
<string name="menu_popup_remove">Убрать</string>
|
||||
<string name="menu_popup_show_qr_code">Показать QR-код</string>
|
||||
<string name="menu_popup_establish_pin">Установить PIN</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Ошибка аутентификации! Пожалуйста, попробуйте снова!</string>
|
||||
<string name="toast_auth_failed_fatal">Ошибка аутентификации, andOTP закрывается!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR-код</string>
|
||||
<string name="dialog_title_android21_depreaction">Уведомление об устаревании</string>
|
||||
<string name="dialog_title_enter_password">Введите пароль</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Введите пароль</string>
|
||||
<string name="dialog_label_confirm_password">Подтвердите пароль</string>
|
||||
<string name="dialog_msg_auth">Пожалуйста, подтвердите учетные данные устройства для открытия andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Vse oznake</string>
|
||||
<string name="button_no_tags">Ni oznak</string>
|
||||
<string name="button_qr_from_image">QR code from image</string>
|
||||
<string name="button_accept">Sprejmi</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Spremeni podobo</string>
|
||||
<string name="menu_popup_remove">Odstrani</string>
|
||||
<string name="menu_popup_show_qr_code">Show QR Code</string>
|
||||
<string name="menu_popup_establish_pin">Nastavite kodo PIN</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Prišlo je do napake pri preverjanju vaše identitete. Prosimo, poskusite ponovno!</string>
|
||||
<string name="toast_auth_failed_fatal">Preverjanje pristnosti ni uspelo, andOTP se zapira!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_android21_depreaction">Deprecation notice</string>
|
||||
<string name="dialog_title_enter_password">Vnesite geslo</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Vnesite geslo</string>
|
||||
<string name="dialog_label_confirm_password">Potrdite geslo</string>
|
||||
<string name="dialog_msg_auth">Prosim, vnesite podatke o napravi za zagon andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Alla taggar</string>
|
||||
<string name="button_no_tags">Inga taggar</string>
|
||||
<string name="button_qr_from_image">QR-kod från bild</string>
|
||||
<string name="button_accept">Acceptera</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Ändra bild</string>
|
||||
<string name="menu_popup_remove">Ta bort</string>
|
||||
<string name="menu_popup_show_qr_code">Visa QR-kod</string>
|
||||
<string name="menu_popup_establish_pin">Ställ in PIN-kod</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Autentisering misslyckades, vänligen försök igen!</string>
|
||||
<string name="toast_auth_failed_fatal">Autentisering misslyckades, stänger andOTP!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR-kod</string>
|
||||
<string name="dialog_title_android21_depreaction">Avskrivningsnotis</string>
|
||||
<string name="dialog_title_enter_password">Ange lösenord</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Ange lösenord</string>
|
||||
<string name="dialog_label_confirm_password">Bekräfta lösenord</string>
|
||||
<string name="dialog_msg_auth">Ange dina enhetsuppgifter för att starta andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Tüm etiketler</string>
|
||||
<string name="button_no_tags">Etiket yok</string>
|
||||
<string name="button_qr_from_image">Görüntüden QR kodu</string>
|
||||
<string name="button_accept">Kabul etmek</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d lar(ler)</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Görseli değiştir</string>
|
||||
<string name="menu_popup_remove">Kaldır</string>
|
||||
<string name="menu_popup_show_qr_code">QR Kodunu Göster</string>
|
||||
<string name="menu_popup_establish_pin">PIN ayarla</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Kimlik doğrulama başarısız oldu, lütfen tekrar deneyin!</string>
|
||||
<string name="toast_auth_failed_fatal">Kimlik doğrulama başarısız oldu, andOTP kapatılıyor!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Kodu</string>
|
||||
<string name="dialog_title_android21_depreaction">Destek sonlandırma bildirimi</string>
|
||||
<string name="dialog_title_enter_password">Şifre girin</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
<string name="dialog_label_enter_password">Şifre Girin</string>
|
||||
<string name="dialog_label_confirm_password">Şifreyi doğrula</string>
|
||||
<string name="dialog_msg_auth">Lütfen andOTP\'yi başlatmak için cihaz kimlik bilgilerinizi girin.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">Усі мітки</string>
|
||||
<string name="button_no_tags">Немає міток</string>
|
||||
<string name="button_qr_from_image">QR code from image</string>
|
||||
<string name="button_accept">Прийміть</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d с</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">Змінити зображення</string>
|
||||
<string name="menu_popup_remove">Видалити</string>
|
||||
<string name="menu_popup_show_qr_code">Show QR Code</string>
|
||||
<string name="menu_popup_establish_pin">Встановити PIN-код</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">Аутентифікація не пройдена. Будь ласка, спробуйте ще раз!</string>
|
||||
<string name="toast_auth_failed_fatal">Автентифікація не пройдена, закриття andOTP!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_android21_depreaction">Deprecation notice</string>
|
||||
<string name="dialog_title_enter_password">Введіть пароль</string>
|
||||
<string name="dialog_title_pin">PIN-код</string>
|
||||
<string name="dialog_label_enter_password">Введіть пароль</string>
|
||||
<string name="dialog_label_confirm_password">Підтвердіть пароль</string>
|
||||
<string name="dialog_msg_auth">Будь ласка, підтвердіть дані вашого пристрою, щоб запустити andOTP.</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">所有标签</string>
|
||||
<string name="button_no_tags">无标签</string>
|
||||
<string name="button_qr_from_image">相册中选择二维码</string>
|
||||
<string name="button_accept">接受</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d 秒</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">更改图像</string>
|
||||
<string name="menu_popup_remove">移除</string>
|
||||
<string name="menu_popup_show_qr_code">显示二维码</string>
|
||||
<string name="menu_popup_establish_pin">设置密码</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">验证失败,请重试!</string>
|
||||
<string name="toast_auth_failed_fatal">验证失败,正在关闭 andOTP!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">二维码</string>
|
||||
<string name="dialog_title_android21_depreaction">禁用通知</string>
|
||||
<string name="dialog_title_enter_password">输入密码</string>
|
||||
<string name="dialog_title_pin">密码</string>
|
||||
<string name="dialog_label_enter_password">输入密码</string>
|
||||
<string name="dialog_label_confirm_password">确认密码</string>
|
||||
<string name="dialog_msg_auth">请输入您的设备凭据以启动 andOTP。</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="button_all_tags">所有標籤</string>
|
||||
<string name="button_no_tags">無標籤</string>
|
||||
<string name="button_qr_from_image">從圖片而來的 QR code</string>
|
||||
<string name="button_accept">接受</string>
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d 秒</string>
|
||||
<!-- Hints -->
|
||||
|
@ -45,6 +46,7 @@
|
|||
<string name="menu_popup_change_image">變更影像</string>
|
||||
<string name="menu_popup_remove">移除</string>
|
||||
<string name="menu_popup_show_qr_code">顯示 QR Code</string>
|
||||
<string name="menu_popup_establish_pin">設置密碼</string>
|
||||
<!-- Toast messages -->
|
||||
<string name="toast_auth_failed">認證失敗,請再試一次!</string>
|
||||
<string name="toast_auth_failed_fatal">認證失敗,andOTP 正在關閉!</string>
|
||||
|
@ -73,6 +75,7 @@
|
|||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_android21_depreaction">棄用通知</string>
|
||||
<string name="dialog_title_enter_password">請輸入密碼</string>
|
||||
<string name="dialog_title_pin">密碼</string>
|
||||
<string name="dialog_label_enter_password">輸入密碼</string>
|
||||
<string name="dialog_label_confirm_password">確認密碼</string>
|
||||
<string name="dialog_msg_auth">請鍵入設備憑證來開啟 andOTP。</string>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<string name="button_all_tags">All tags</string>
|
||||
<string name="button_no_tags">No tags</string>
|
||||
<string name="button_qr_from_image">QR code from image</string>
|
||||
<string name="button_accept">Accept</string>
|
||||
|
||||
<!-- Custom formatting -->
|
||||
<string name="format_custom_period">%d s</string>
|
||||
|
@ -56,6 +57,7 @@
|
|||
<string name="menu_popup_change_image">Change image</string>
|
||||
<string name="menu_popup_remove">Remove</string>
|
||||
<string name="menu_popup_show_qr_code">Show QR Code</string>
|
||||
<string name="menu_popup_establish_pin">Enter pin</string>
|
||||
|
||||
<!-- Buttons -->
|
||||
<string name="button_card_options">More options</string>
|
||||
|
@ -93,6 +95,7 @@
|
|||
<string name="dialog_title_used_tokens">Tokens usage</string>
|
||||
<string name="dialog_title_keystore_error">KeyStore error</string>
|
||||
<string name="dialog_title_qr_code">QR Code</string>
|
||||
<string name="dialog_title_pin">PIN</string>
|
||||
|
||||
<string name="dialog_title_enter_password">Enter password</string>
|
||||
|
||||
|
|
Loading…
Reference in a new issue