Fixes #138- delays identicon update to avoid leaking interactive keyboard input.
This commit is contained in:
parent
c3f4d148a4
commit
77bee803b8
@ -10,7 +10,7 @@ To skip the intro and go straight to the information on how to use the code, [cl
|
||||
|
||||
Master Password is available for [📲 iOS](https://itunes.apple.com/app/id510296984), [🖥 macOS](https://ssl.masterpasswordapp.com/masterpassword-mac.zip), [📲 Android](https://ssl.masterpasswordapp.com/masterpassword-android.apk), [🖥 Desktop](https://ssl.masterpasswordapp.com/masterpassword-gui.jar), and [⌨ Console](https://ssl.masterpasswordapp.com/masterpassword-cli.tar.gz).
|
||||
|
||||
Master Password is also available from the following package managers: [mac OS: Homebrew](https://brew.sh/). Get in touch if you are interested in adding Master Password to any other package managers.
|
||||
Master Password is also available from the following package managers: [macOS: Homebrew](https://brew.sh/). Get in touch if you are interested in adding Master Password to any other package managers.
|
||||
|
||||
## What is a password?
|
||||
|
||||
|
@ -1,12 +1,15 @@
|
||||
apply plugin: 'java'
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
description = 'Master Password Algorithm Implementation'
|
||||
|
||||
dependencies {
|
||||
compile( 'com.lyndir.lhunath.opal:opal-system:1.6-p10' ) {
|
||||
compile (group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.6-p10') {
|
||||
exclude( module: 'joda-time' )
|
||||
}
|
||||
compile 'com.lambdaworks:scrypt:1.4.0'
|
||||
compile 'org.jetbrains:annotations:13.0'
|
||||
compile 'com.google.code.findbugs:jsr305:3.0.1'
|
||||
|
||||
compile group: 'com.lambdaworks', name: 'scrypt', version: '1.4.0'
|
||||
compile group: 'org.jetbrains', name: 'annotations', version: '13.0'
|
||||
compile group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1'
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ dependencies {
|
||||
compile project(':masterpassword:algorithm')
|
||||
|
||||
compile group: 'joda-time', name: 'joda-time', version:'2.4'
|
||||
|
||||
compileOnly group: 'com.google.auto.value', name: 'auto-value', version: '1.2'
|
||||
apt group: 'com.google.auto.value', name: 'auto-value', version: '1.2'
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
apply plugin: 'java'
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
description = 'Master Password Test Suite'
|
||||
|
||||
dependencies {
|
||||
compile project(':masterpassword:algorithm')
|
||||
compile project(':masterpassword:algorithm')
|
||||
|
||||
testCompile group: 'org.testng', name: 'testng', version:'6.8.5'
|
||||
testCompile group: 'ch.qos.logback', name: 'logback-classic', version:'1.1.2'
|
||||
|
@ -2,14 +2,10 @@ package com.lyndir.masterpassword;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import com.lyndir.lhunath.opal.system.CodeUtils;
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import com.lyndir.lhunath.opal.system.util.NNFunctionNN;
|
||||
import com.lyndir.lhunath.opal.system.util.StringUtils;
|
||||
import java.net.URL;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@ -88,7 +84,7 @@ public class MasterKeyTest {
|
||||
masterKey.encode( defaultCase.getSiteName(), defaultCase.getSiteType(), defaultCase.getSiteCounter(),
|
||||
defaultCase.getSiteVariant(), defaultCase.getSiteContext() );
|
||||
|
||||
assertTrue( false, "[testInvalidate] Master key should have been invalidated, but was still usable." );
|
||||
fail( "[testInvalidate] Master key should have been invalidated, but was still usable." );
|
||||
}
|
||||
catch (IllegalStateException ignored) {
|
||||
}
|
||||
|
30
gradle/.idea/runConfigurations/Android.xml
Normal file
30
gradle/.idea/runConfigurations/Android.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Android" type="AndroidRunConfigurationType" factoryName="Android App">
|
||||
<module name="android" />
|
||||
<option name="DEPLOY" value="true" />
|
||||
<option name="ARTIFACT_NAME" value="" />
|
||||
<option name="PM_INSTALL_OPTIONS" value="" />
|
||||
<option name="ACTIVITY_EXTRA_FLAGS" value="" />
|
||||
<option name="MODE" value="default_activity" />
|
||||
<option name="TARGET_SELECTION_MODE" value="SHOW_DIALOG" />
|
||||
<option name="PREFERRED_AVD" value="" />
|
||||
<option name="CLEAR_LOGCAT" value="false" />
|
||||
<option name="SHOW_LOGCAT_AUTOMATICALLY" value="false" />
|
||||
<option name="SKIP_NOOP_APK_INSTALLATIONS" value="true" />
|
||||
<option name="FORCE_STOP_RUNNING_APP" value="true" />
|
||||
<option name="DEBUGGER_TYPE" value="Java" />
|
||||
<option name="USE_LAST_SELECTED_DEVICE" value="false" />
|
||||
<option name="PREFERRED_AVD" value="" />
|
||||
<Java />
|
||||
<Profilers>
|
||||
<option name="ENABLE_ADVANCED_PROFILING" value="false" />
|
||||
<option name="GAPID_ENABLED" value="false" />
|
||||
<option name="GAPID_DISABLE_PCS" value="false" />
|
||||
<option name="SUPPORT_LIB_ENABLED" value="true" />
|
||||
<option name="INSTRUMENTATION_ENABLED" value="true" />
|
||||
</Profilers>
|
||||
<option name="DEEP_LINK" value="" />
|
||||
<option name="ACTIVITY_CLASS" value="" />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
16
gradle/.idea/runConfigurations/GUI.xml
Normal file
16
gradle/.idea/runConfigurations/GUI.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="GUI" type="Application" factoryName="Application">
|
||||
<option name="MAIN_CLASS_NAME" value="com.lyndir.masterpassword.gui.GUI" />
|
||||
<option name="VM_PARAMETERS" value="" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="ENABLE_SWING_INSPECTOR" value="false" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<module name="gui" />
|
||||
<envs />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
29
gradle/.idea/runConfigurations/Tests.xml
Normal file
29
gradle/.idea/runConfigurations/Tests.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Tests" type="TestNG" factoryName="TestNG">
|
||||
<module name="tests" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="SUITE_NAME" value="" />
|
||||
<option name="PACKAGE_NAME" value="com.lyndir.masterpassword" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="GROUP_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="PACKAGE" />
|
||||
<option name="VM_PARAMETERS" value="-ea" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/../core/java/tests" />
|
||||
<option name="OUTPUT_DIRECTORY" value="" />
|
||||
<option name="ANNOTATION_TYPE" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="singleModule" />
|
||||
</option>
|
||||
<option name="USE_DEFAULT_REPORTERS" value="false" />
|
||||
<option name="PROPERTIES_FILE" value="" />
|
||||
<envs />
|
||||
<properties />
|
||||
<listeners />
|
||||
<method />
|
||||
</configuration>
|
||||
</component>
|
@ -1,12 +1,12 @@
|
||||
allprojects {
|
||||
allprojects {
|
||||
//apply plugin: 'findbugs'
|
||||
|
||||
group = 'com.lyndir.masterpassword'
|
||||
version = 'GIT-SNAPSHOT'
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
sourceCompatibility = "1.7"
|
||||
targetCompatibility = "1.7"
|
||||
sourceCompatibility = '1.7'
|
||||
targetCompatibility = '1.7'
|
||||
}
|
||||
tasks.withType(FindBugs) {
|
||||
reports {
|
||||
@ -29,6 +29,6 @@ buildscript {
|
||||
subprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "http://maven.lyndir.com" }
|
||||
maven { url 'http://maven.lyndir.com' }
|
||||
}
|
||||
}
|
||||
|
@ -2,44 +2,45 @@ apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion "25.0.0"
|
||||
buildToolsVersion '25.0.0'
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.lyndir.masterpassword"
|
||||
applicationId 'com.lyndir.masterpassword'
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 25
|
||||
versionCode 20401
|
||||
versionName "2.4.1"
|
||||
versionName '2.4.1'
|
||||
}
|
||||
|
||||
// release with: STORE_PW=$(mpw masterpassword.keystore) KEY_PW=$(mpw masterpassword-android) gradle assembleRelease
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file('masterpassword.keystore')
|
||||
storePassword System.getenv('STORE_PW')
|
||||
storeFile file( 'masterpassword.keystore' )
|
||||
storePassword System.getenv( 'STORE_PW' )
|
||||
|
||||
keyAlias 'masterpassword-android'
|
||||
keyPassword System.getenv('KEY_PW')
|
||||
keyPassword System.getenv( 'KEY_PW' )
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
if (System.getenv('STORE_PW') != null)
|
||||
if (System.getenv( 'STORE_PW' ) != null)
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project( ':masterpassword:algorithm' )
|
||||
compile project( ':masterpassword:tests' )
|
||||
compile project( ':masterpassword:algorithm' )
|
||||
compile project( ':masterpassword:tests' )
|
||||
|
||||
// Android dependencies
|
||||
compile 'org.slf4j:slf4j-android:1.7.13-underscore'
|
||||
compile 'com.jakewharton:butterknife:8.5.1'
|
||||
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
|
||||
compile files('libs/scrypt-1.4.0-native.jar')
|
||||
compile group: 'org.slf4j', name: 'slf4j-android', version:'1.7.13-underscore'
|
||||
compile group: 'com.jakewharton', name: 'butterknife', version:'8.5.1'
|
||||
annotationProcessor group: 'com.jakewharton', name: 'butterknife-compiler', version:'8.5.1'
|
||||
compile files( 'libs/scrypt-1.4.0-native.jar' )
|
||||
}
|
||||
|
@ -22,6 +22,9 @@ import com.google.common.io.*;
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import com.lyndir.lhunath.opal.system.util.TypeUtils;
|
||||
|
||||
import com.lyndir.masterpassword.gui.model.User;
|
||||
import com.lyndir.masterpassword.gui.view.PasswordFrame;
|
||||
import com.lyndir.masterpassword.gui.view.UnlockFrame;
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
@ -30,12 +30,16 @@ import javax.swing.*;
|
||||
*/
|
||||
public abstract class Res {
|
||||
|
||||
private static final WeakHashMap<Window, ExecutorService> executorByWindow = new WeakHashMap<>();
|
||||
private static final Logger logger = Logger.get( Res.class );
|
||||
private static final Colors colors = new Colors();
|
||||
private static final WeakHashMap<Window, ScheduledExecutorService> executorByWindow = new WeakHashMap<>();
|
||||
private static final Logger logger = Logger.get( Res.class );
|
||||
private static final Colors colors = new Colors();
|
||||
|
||||
public static Future<?> execute(final Window host, final Runnable job) {
|
||||
return getExecutor( host ).submit( new Runnable() {
|
||||
return schedule( host, job, 0, TimeUnit.MILLISECONDS );
|
||||
}
|
||||
|
||||
public static Future<?> schedule(final Window host, final Runnable job, final long delay, final TimeUnit timeUnit) {
|
||||
return getExecutor( host ).schedule( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@ -45,12 +49,16 @@ public abstract class Res {
|
||||
logger.err( t, "Unexpected: %s", t.getLocalizedMessage() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}, delay, timeUnit );
|
||||
}
|
||||
|
||||
public static <V> ListenableFuture<V> execute(final Window host, final Callable<V> job) {
|
||||
ExecutorService executor = getExecutor( host );
|
||||
return JdkFutureAdapters.listenInPoolThread( executor.submit( new Callable<V>() {
|
||||
return schedule( host, job, 0, TimeUnit.MILLISECONDS );
|
||||
}
|
||||
|
||||
public static <V> ListenableFuture<V> schedule(final Window host, final Callable<V> job, final long delay, final TimeUnit timeUnit) {
|
||||
ScheduledExecutorService executor = getExecutor( host );
|
||||
return JdkFutureAdapters.listenInPoolThread( executor.schedule( new Callable<V>() {
|
||||
@Override
|
||||
public V call()
|
||||
throws Exception {
|
||||
@ -62,14 +70,14 @@ public abstract class Res {
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
} ), executor );
|
||||
}, delay, timeUnit ), executor );
|
||||
}
|
||||
|
||||
private static ExecutorService getExecutor(final Window host) {
|
||||
ExecutorService executor = executorByWindow.get( host );
|
||||
private static ScheduledExecutorService getExecutor(final Window host) {
|
||||
ScheduledExecutorService executor = executorByWindow.get( host );
|
||||
|
||||
if (executor == null) {
|
||||
executorByWindow.put( host, executor = Executors.newSingleThreadExecutor() );
|
||||
executorByWindow.put( host, executor = Executors.newSingleThreadScheduledExecutor() );
|
||||
|
||||
host.addWindowListener( new WindowAdapter() {
|
||||
@Override
|
||||
@ -252,8 +260,8 @@ public abstract class Res {
|
||||
|
||||
public static class Colors {
|
||||
|
||||
private final Color frameBg = Color.decode( "#5A5D6B" );
|
||||
private final Color controlBg = Color.decode( "#ECECEC" );
|
||||
private final Color frameBg = Color.decode( "#5A5D6B" );
|
||||
private final Color controlBg = Color.decode( "#ECECEC" );
|
||||
private final Color controlBorder = Color.decode( "#BFBFBF" );
|
||||
|
||||
public Color frameBg() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.model;
|
||||
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import com.lyndir.masterpassword.MPSiteType;
|
@ -1,4 +1,4 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.model;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.lyndir.masterpassword.model.IncorrectMasterPasswordException;
|
@ -1,4 +1,4 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.model;
|
||||
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import com.lyndir.masterpassword.MPSiteType;
|
@ -1,8 +1,9 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.model;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.lyndir.masterpassword.gui.*;
|
||||
import com.lyndir.masterpassword.model.*;
|
||||
import java.util.Arrays;
|
||||
import javax.annotation.Nullable;
|
||||
@ -43,7 +44,7 @@ public class ModelUser extends User {
|
||||
}
|
||||
|
||||
public void setAvatar(final int avatar) {
|
||||
model.setAvatar(avatar % Res.avatars());
|
||||
model.setAvatar( avatar % Res.avatars());
|
||||
MPUserFileManager.get().save();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.model;
|
||||
|
||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.model;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Maps;
|
@ -2,8 +2,8 @@ package com.lyndir.masterpassword.gui.platform.mac;
|
||||
|
||||
import com.apple.eawt.*;
|
||||
import com.lyndir.masterpassword.gui.GUI;
|
||||
import com.lyndir.masterpassword.gui.PasswordFrame;
|
||||
import com.lyndir.masterpassword.gui.User;
|
||||
import com.lyndir.masterpassword.gui.view.PasswordFrame;
|
||||
import com.lyndir.masterpassword.gui.model.User;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.view;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.lyndir.masterpassword.MPIdenticon;
|
||||
import com.lyndir.masterpassword.gui.Res;
|
||||
import com.lyndir.masterpassword.gui.model.User;
|
||||
import com.lyndir.masterpassword.gui.util.Components;
|
||||
import com.lyndir.masterpassword.gui.view.UnlockFrame;
|
||||
import java.awt.*;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
@ -1,5 +1,8 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.view;
|
||||
|
||||
import com.lyndir.masterpassword.gui.Res;
|
||||
import com.lyndir.masterpassword.gui.model.IncognitoUser;
|
||||
import com.lyndir.masterpassword.gui.model.User;
|
||||
import com.lyndir.masterpassword.gui.util.Components;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
@ -1,4 +1,4 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.view;
|
||||
|
||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||
|
||||
@ -6,6 +6,8 @@ import com.google.common.base.Function;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.*;
|
||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||
import com.lyndir.masterpassword.gui.Res;
|
||||
import com.lyndir.masterpassword.gui.model.ModelUser;
|
||||
import com.lyndir.masterpassword.model.MPUser;
|
||||
import com.lyndir.masterpassword.model.MPUserFileManager;
|
||||
import com.lyndir.masterpassword.gui.util.Components;
|
@ -1,4 +1,4 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.view;
|
||||
|
||||
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.ifNotNullElse;
|
||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.*;
|
||||
@ -9,6 +9,8 @@ import com.google.common.collect.Iterables;
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
import com.google.common.util.concurrent.*;
|
||||
import com.lyndir.masterpassword.*;
|
||||
import com.lyndir.masterpassword.gui.Res;
|
||||
import com.lyndir.masterpassword.gui.model.*;
|
||||
import com.lyndir.masterpassword.gui.util.Components;
|
||||
import com.lyndir.masterpassword.gui.util.UnsignedIntegerModel;
|
||||
import java.awt.*;
|
@ -1,12 +1,16 @@
|
||||
package com.lyndir.masterpassword.gui;
|
||||
package com.lyndir.masterpassword.gui.view;
|
||||
|
||||
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
|
||||
|
||||
import com.lyndir.masterpassword.MPIdenticon;
|
||||
import com.lyndir.masterpassword.gui.*;
|
||||
import com.lyndir.masterpassword.gui.model.User;
|
||||
import com.lyndir.masterpassword.gui.util.Components;
|
||||
import com.lyndir.masterpassword.model.IncorrectMasterPasswordException;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.swing.*;
|
||||
|
||||
@ -22,6 +26,7 @@ public class UnlockFrame extends JFrame {
|
||||
private final JButton signInButton;
|
||||
private final JPanel authenticationContainer;
|
||||
private AuthenticationPanel authenticationPanel;
|
||||
private Future<?> identiconFuture;
|
||||
private boolean incognito;
|
||||
public User user;
|
||||
|
||||
@ -139,18 +144,34 @@ public class UnlockFrame extends JFrame {
|
||||
}
|
||||
|
||||
boolean checkSignIn() {
|
||||
if (identiconFuture != null)
|
||||
identiconFuture.cancel( false );
|
||||
identiconFuture = Res.schedule( this, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SwingUtilities.invokeLater( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String fullName = user == null? "": user.getFullName();
|
||||
char[] masterPassword = authenticationPanel.getMasterPassword();
|
||||
|
||||
if (fullName.isEmpty() || masterPassword.length == 0) {
|
||||
identiconLabel.setText( " " );
|
||||
return;
|
||||
}
|
||||
|
||||
MPIdenticon identicon = new MPIdenticon( fullName, masterPassword );
|
||||
identiconLabel.setText( identicon.getText() );
|
||||
identiconLabel.setForeground(
|
||||
Res.colors().fromIdenticonColor( identicon.getColor(), Res.Colors.BackgroundMode.DARK ) );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}, 300, TimeUnit.MILLISECONDS );
|
||||
|
||||
String fullName = user == null? "": user.getFullName();
|
||||
char[] masterPassword = authenticationPanel.getMasterPassword();
|
||||
boolean enabled = !fullName.isEmpty() && masterPassword.length > 0;
|
||||
|
||||
if (fullName.isEmpty() || masterPassword.length == 0)
|
||||
identiconLabel.setText( " " );
|
||||
else {
|
||||
MPIdenticon identicon = new MPIdenticon( fullName, masterPassword );
|
||||
identiconLabel.setText( identicon.getText() );
|
||||
identiconLabel.setForeground( Res.colors().fromIdenticonColor( identicon.getColor(), Res.Colors.BackgroundMode.DARK ) );
|
||||
}
|
||||
|
||||
signInButton.setEnabled( enabled );
|
||||
|
||||
return enabled;
|
||||
@ -197,7 +218,7 @@ public class UnlockFrame extends JFrame {
|
||||
} );
|
||||
}
|
||||
|
||||
interface SignInCallback {
|
||||
public interface SignInCallback {
|
||||
|
||||
void signedIn(User user);
|
||||
}
|
Loading…
Reference in New Issue
Block a user