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 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?
|
## What is a password?
|
||||||
|
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
apply plugin: 'java'
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
description = 'Master Password Algorithm Implementation'
|
description = 'Master Password Algorithm Implementation'
|
||||||
|
|
||||||
dependencies {
|
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' )
|
exclude( module: 'joda-time' )
|
||||||
}
|
}
|
||||||
compile 'com.lambdaworks:scrypt:1.4.0'
|
|
||||||
compile 'org.jetbrains:annotations:13.0'
|
compile group: 'com.lambdaworks', name: 'scrypt', version: '1.4.0'
|
||||||
compile 'com.google.code.findbugs:jsr305:3.0.1'
|
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 project(':masterpassword:algorithm')
|
||||||
|
|
||||||
compile group: 'joda-time', name: 'joda-time', version:'2.4'
|
compile group: 'joda-time', name: 'joda-time', version:'2.4'
|
||||||
|
|
||||||
compileOnly group: 'com.google.auto.value', name: 'auto-value', version: '1.2'
|
compileOnly group: 'com.google.auto.value', name: 'auto-value', version: '1.2'
|
||||||
apt group: 'com.google.auto.value', name: 'auto-value', version: '1.2'
|
apt group: 'com.google.auto.value', name: 'auto-value', version: '1.2'
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
apply plugin: 'java'
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
description = 'Master Password Test Suite'
|
description = 'Master Password Test Suite'
|
||||||
|
|
||||||
|
@ -2,14 +2,10 @@ package com.lyndir.masterpassword;
|
|||||||
|
|
||||||
import static org.testng.Assert.*;
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
import com.google.common.io.Resources;
|
|
||||||
import com.lyndir.lhunath.opal.system.CodeUtils;
|
import com.lyndir.lhunath.opal.system.CodeUtils;
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||||
import com.lyndir.lhunath.opal.system.util.NNFunctionNN;
|
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.annotation.Nonnull;
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
@ -88,7 +84,7 @@ public class MasterKeyTest {
|
|||||||
masterKey.encode( defaultCase.getSiteName(), defaultCase.getSiteType(), defaultCase.getSiteCounter(),
|
masterKey.encode( defaultCase.getSiteName(), defaultCase.getSiteType(), defaultCase.getSiteCounter(),
|
||||||
defaultCase.getSiteVariant(), defaultCase.getSiteContext() );
|
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) {
|
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>
|
@ -5,8 +5,8 @@ allprojects {
|
|||||||
version = 'GIT-SNAPSHOT'
|
version = 'GIT-SNAPSHOT'
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
sourceCompatibility = "1.7"
|
sourceCompatibility = '1.7'
|
||||||
targetCompatibility = "1.7"
|
targetCompatibility = '1.7'
|
||||||
}
|
}
|
||||||
tasks.withType(FindBugs) {
|
tasks.withType(FindBugs) {
|
||||||
reports {
|
reports {
|
||||||
@ -29,6 +29,6 @@ buildscript {
|
|||||||
subprojects {
|
subprojects {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url "http://maven.lyndir.com" }
|
maven { url 'http://maven.lyndir.com' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,32 +2,34 @@ apply plugin: 'com.android.application'
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 25
|
compileSdkVersion 25
|
||||||
buildToolsVersion "25.0.0"
|
buildToolsVersion '25.0.0'
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_7
|
sourceCompatibility JavaVersion.VERSION_1_7
|
||||||
targetCompatibility JavaVersion.VERSION_1_7
|
targetCompatibility JavaVersion.VERSION_1_7
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.lyndir.masterpassword"
|
applicationId 'com.lyndir.masterpassword'
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 20401
|
versionCode 20401
|
||||||
versionName "2.4.1"
|
versionName '2.4.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
// release with: STORE_PW=$(mpw masterpassword.keystore) KEY_PW=$(mpw masterpassword-android) gradle assembleRelease
|
// release with: STORE_PW=$(mpw masterpassword.keystore) KEY_PW=$(mpw masterpassword-android) gradle assembleRelease
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
release {
|
release {
|
||||||
storeFile file('masterpassword.keystore')
|
storeFile file( 'masterpassword.keystore' )
|
||||||
storePassword System.getenv('STORE_PW')
|
storePassword System.getenv( 'STORE_PW' )
|
||||||
|
|
||||||
keyAlias 'masterpassword-android'
|
keyAlias 'masterpassword-android'
|
||||||
keyPassword System.getenv('KEY_PW')
|
keyPassword System.getenv( 'KEY_PW' )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
if (System.getenv('STORE_PW') != null)
|
if (System.getenv( 'STORE_PW' ) != null)
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,9 +39,8 @@ dependencies {
|
|||||||
compile project( ':masterpassword:algorithm' )
|
compile project( ':masterpassword:algorithm' )
|
||||||
compile project( ':masterpassword:tests' )
|
compile project( ':masterpassword:tests' )
|
||||||
|
|
||||||
// Android dependencies
|
compile group: 'org.slf4j', name: 'slf4j-android', version:'1.7.13-underscore'
|
||||||
compile 'org.slf4j:slf4j-android:1.7.13-underscore'
|
compile group: 'com.jakewharton', name: 'butterknife', version:'8.5.1'
|
||||||
compile 'com.jakewharton:butterknife:8.5.1'
|
annotationProcessor group: 'com.jakewharton', name: 'butterknife-compiler', version:'8.5.1'
|
||||||
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
|
compile files( 'libs/scrypt-1.4.0-native.jar' )
|
||||||
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.logging.Logger;
|
||||||
import com.lyndir.lhunath.opal.system.util.TypeUtils;
|
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.io.*;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -30,12 +30,16 @@ import javax.swing.*;
|
|||||||
*/
|
*/
|
||||||
public abstract class Res {
|
public abstract class Res {
|
||||||
|
|
||||||
private static final WeakHashMap<Window, ExecutorService> executorByWindow = new WeakHashMap<>();
|
private static final WeakHashMap<Window, ScheduledExecutorService> executorByWindow = new WeakHashMap<>();
|
||||||
private static final Logger logger = Logger.get( Res.class );
|
private static final Logger logger = Logger.get( Res.class );
|
||||||
private static final Colors colors = new Colors();
|
private static final Colors colors = new Colors();
|
||||||
|
|
||||||
public static Future<?> execute(final Window host, final Runnable job) {
|
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
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
@ -45,12 +49,16 @@ public abstract class Res {
|
|||||||
logger.err( t, "Unexpected: %s", t.getLocalizedMessage() );
|
logger.err( t, "Unexpected: %s", t.getLocalizedMessage() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} );
|
}, delay, timeUnit );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <V> ListenableFuture<V> execute(final Window host, final Callable<V> job) {
|
public static <V> ListenableFuture<V> execute(final Window host, final Callable<V> job) {
|
||||||
ExecutorService executor = getExecutor( host );
|
return schedule( host, job, 0, TimeUnit.MILLISECONDS );
|
||||||
return JdkFutureAdapters.listenInPoolThread( executor.submit( new Callable<V>() {
|
}
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
public V call()
|
public V call()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@ -62,14 +70,14 @@ public abstract class Res {
|
|||||||
throw t;
|
throw t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ), executor );
|
}, delay, timeUnit ), executor );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ExecutorService getExecutor(final Window host) {
|
private static ScheduledExecutorService getExecutor(final Window host) {
|
||||||
ExecutorService executor = executorByWindow.get( host );
|
ScheduledExecutorService executor = executorByWindow.get( host );
|
||||||
|
|
||||||
if (executor == null) {
|
if (executor == null) {
|
||||||
executorByWindow.put( host, executor = Executors.newSingleThreadExecutor() );
|
executorByWindow.put( host, executor = Executors.newSingleThreadScheduledExecutor() );
|
||||||
|
|
||||||
host.addWindowListener( new WindowAdapter() {
|
host.addWindowListener( new WindowAdapter() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.lyndir.masterpassword.gui;
|
package com.lyndir.masterpassword.gui.model;
|
||||||
|
|
||||||
import com.google.common.primitives.UnsignedInteger;
|
import com.google.common.primitives.UnsignedInteger;
|
||||||
import com.lyndir.masterpassword.MPSiteType;
|
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.google.common.collect.ImmutableList;
|
||||||
import com.lyndir.masterpassword.model.IncorrectMasterPasswordException;
|
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.google.common.primitives.UnsignedInteger;
|
||||||
import com.lyndir.masterpassword.MPSiteType;
|
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.Function;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.FluentIterable;
|
import com.google.common.collect.FluentIterable;
|
||||||
|
import com.lyndir.masterpassword.gui.*;
|
||||||
import com.lyndir.masterpassword.model.*;
|
import com.lyndir.masterpassword.model.*;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -43,7 +44,7 @@ public class ModelUser extends User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setAvatar(final int avatar) {
|
public void setAvatar(final int avatar) {
|
||||||
model.setAvatar(avatar % Res.avatars());
|
model.setAvatar( avatar % Res.avatars());
|
||||||
MPUserFileManager.get().save();
|
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;
|
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.base.Preconditions;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
@ -2,8 +2,8 @@ package com.lyndir.masterpassword.gui.platform.mac;
|
|||||||
|
|
||||||
import com.apple.eawt.*;
|
import com.apple.eawt.*;
|
||||||
import com.lyndir.masterpassword.gui.GUI;
|
import com.lyndir.masterpassword.gui.GUI;
|
||||||
import com.lyndir.masterpassword.gui.PasswordFrame;
|
import com.lyndir.masterpassword.gui.view.PasswordFrame;
|
||||||
import com.lyndir.masterpassword.gui.User;
|
import com.lyndir.masterpassword.gui.model.User;
|
||||||
|
|
||||||
import javax.swing.*;
|
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.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.util.Components;
|
||||||
|
import com.lyndir.masterpassword.gui.view.UnlockFrame;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
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 com.lyndir.masterpassword.gui.util.Components;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ActionEvent;
|
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;
|
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.base.Preconditions;
|
||||||
import com.google.common.collect.*;
|
import com.google.common.collect.*;
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
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.MPUser;
|
||||||
import com.lyndir.masterpassword.model.MPUserFileManager;
|
import com.lyndir.masterpassword.model.MPUserFileManager;
|
||||||
import com.lyndir.masterpassword.gui.util.Components;
|
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.ObjectUtils.ifNotNullElse;
|
||||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.*;
|
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.primitives.UnsignedInteger;
|
||||||
import com.google.common.util.concurrent.*;
|
import com.google.common.util.concurrent.*;
|
||||||
import com.lyndir.masterpassword.*;
|
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.Components;
|
||||||
import com.lyndir.masterpassword.gui.util.UnsignedIntegerModel;
|
import com.lyndir.masterpassword.gui.util.UnsignedIntegerModel;
|
||||||
import java.awt.*;
|
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 static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
|
||||||
|
|
||||||
import com.lyndir.masterpassword.MPIdenticon;
|
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.gui.util.Components;
|
||||||
import com.lyndir.masterpassword.model.IncorrectMasterPasswordException;
|
import com.lyndir.masterpassword.model.IncorrectMasterPasswordException;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
@ -22,6 +26,7 @@ public class UnlockFrame extends JFrame {
|
|||||||
private final JButton signInButton;
|
private final JButton signInButton;
|
||||||
private final JPanel authenticationContainer;
|
private final JPanel authenticationContainer;
|
||||||
private AuthenticationPanel authenticationPanel;
|
private AuthenticationPanel authenticationPanel;
|
||||||
|
private Future<?> identiconFuture;
|
||||||
private boolean incognito;
|
private boolean incognito;
|
||||||
public User user;
|
public User user;
|
||||||
|
|
||||||
@ -139,18 +144,34 @@ public class UnlockFrame extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean checkSignIn() {
|
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();
|
String fullName = user == null? "": user.getFullName();
|
||||||
char[] masterPassword = authenticationPanel.getMasterPassword();
|
char[] masterPassword = authenticationPanel.getMasterPassword();
|
||||||
boolean enabled = !fullName.isEmpty() && masterPassword.length > 0;
|
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 );
|
signInButton.setEnabled( enabled );
|
||||||
|
|
||||||
return enabled;
|
return enabled;
|
||||||
@ -197,7 +218,7 @@ public class UnlockFrame extends JFrame {
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SignInCallback {
|
public interface SignInCallback {
|
||||||
|
|
||||||
void signedIn(User user);
|
void signedIn(User user);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user