2
0

Compare commits

...

22 Commits

Author SHA1 Message Date
Maarten Billemont
f21d0f7cfc [maven-release-plugin] prepare release 2.4-java 2016-02-20 22:29:27 -05:00
Maarten Billemont
7eb10cb5a6 Fix a bug with storing the default algorithm version. 2016-02-20 22:26:50 -05:00
Maarten Billemont
64829c99d8 Initial support for security questions in Mac app. 2016-02-20 21:56:04 -05:00
Maarten Billemont
0269c2741a Silence warning when releasing about jarsigner version ambiguity. 2016-02-20 21:53:58 -05:00
Maarten Billemont
f5638ea798 A little clean-up. 2016-02-20 21:48:18 -05:00
Maarten Billemont
6a1768a50d Fixed a few bugs. 2016-02-20 21:45:11 -05:00
Maarten Billemont
b346b3be65 Finish up Android UI improvements. 2016-02-20 21:27:59 -05:00
Maarten Billemont
060ec0b5cd Move preferences into a global preferences controller. 2016-02-20 20:30:08 -05:00
Maarten Billemont
7f8a36e32e Added ability to switch from native to java-only KDF. 2016-02-20 18:50:44 -05:00
Maarten Billemont
024899f311 Updated and fixed encoding of a few PNGs. 2016-02-20 18:49:21 -05:00
Maarten Billemont
6ffef78469 Fix some C warnings. 2016-02-19 08:34:06 -05:00
Maarten Billemont
b574158d92 Update logback layout to new format. 2016-02-19 08:25:14 -05:00
Maarten Billemont
7c97cd7a6d Crashlytics for Mac update. 2016-01-27 21:40:09 -05:00
Maarten Billemont
0aa47cc3f4 Mac build fixes and Fabric integration. 2016-01-27 21:38:36 -05:00
Maarten Billemont
39b380b938 Add TouchID to storeVersions and update crypto libs for bitcode. 2016-01-15 00:19:07 -05:00
Maarten Billemont
e6fdd8859e Update copyright. 2016-01-14 11:24:27 -05:00
Maarten Billemont
de70e871a2 Fixes to TouchID in-app checks. 2016-01-14 11:22:15 -05:00
Maarten Billemont
225e932fe7 Enable In-App purchase of TouchID feature and improved auto-height calculation of preferences and store table cells. 2016-01-14 10:50:03 -05:00
Maarten Billemont
61b4ea4525 Finish TouchID support. 2016-01-14 09:58:04 -05:00
Maarten Billemont
a42edec918 TouchID integration and fixes to PearlLogger integration into mpw C code. 2016-01-14 02:14:36 -05:00
Maarten Billemont
360b20d06f Make output verbosity configurable from the CLI and standardize options. 2016-01-04 14:52:05 -05:00
Maarten Billemont
6bc8fa1a6a [maven-release-plugin] rollback changes from release preparation of 2.3.1 2015-12-24 23:32:47 -05:00
133 changed files with 1520 additions and 1006 deletions

View File

@@ -5,7 +5,6 @@
<inspection_tool class="Convert to string" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="Convert to string" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="FunctionImplicitDeclarationInspection" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="FunctionImplicitDeclarationInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ImplicitIntegerAndEnumConversion" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="ImplicitIntegerAndEnumConversion" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LossyEncoding" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MethodIsLaterInTheScope" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="MethodIsLaterInTheScope" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCNotLocalizedStringInspection" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="OCNotLocalizedStringInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCUnusedMacroInspection" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="OCUnusedMacroInspection" enabled="false" level="WARNING" enabled_by_default="false" />

View File

@@ -10,6 +10,10 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
/**
* This class exposes the Answers Events API, allowing you to track key
* user user actions and metrics in your app.
*/
@interface Answers : NSObject @interface Answers : NSObject
/** /**
@@ -18,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
* *
* @param signUpMethodOrNil The method by which a user logged in, e.g. Twitter or Digits. * @param signUpMethodOrNil The method by which a user logged in, e.g. Twitter or Digits.
* @param signUpSucceededOrNil The ultimate success or failure of the login * @param signUpSucceededOrNil The ultimate success or failure of the login
* @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase. * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
*/ */
+ (void)logSignUpWithMethod:(nullable NSString *)signUpMethodOrNil + (void)logSignUpWithMethod:(nullable NSString *)signUpMethodOrNil
success:(nullable NSNumber *)signUpSucceededOrNil success:(nullable NSNumber *)signUpSucceededOrNil
@@ -30,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN
* *
* @param loginMethodOrNil The method by which a user logged in, e.g. email, Twitter or Digits. * @param loginMethodOrNil The method by which a user logged in, e.g. email, Twitter or Digits.
* @param loginSucceededOrNil The ultimate success or failure of the login * @param loginSucceededOrNil The ultimate success or failure of the login
* @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase. * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
*/ */
+ (void)logLoginWithMethod:(nullable NSString *)loginMethodOrNil + (void)logLoginWithMethod:(nullable NSString *)loginMethodOrNil
success:(nullable NSNumber *)loginSucceededOrNil success:(nullable NSNumber *)loginSucceededOrNil
@@ -57,7 +61,7 @@ NS_ASSUME_NONNULL_BEGIN
* your application. * your application.
* *
* @param inviteMethodOrNil The method of invitation, e.g. GameCenter, Twitter, email. * @param inviteMethodOrNil The method of invitation, e.g. GameCenter, Twitter, email.
* @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase. * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
*/ */
+ (void)logInviteWithMethod:(nullable NSString *)inviteMethodOrNil + (void)logInviteWithMethod:(nullable NSString *)inviteMethodOrNil
customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil; customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
@@ -70,8 +74,8 @@ NS_ASSUME_NONNULL_BEGIN
* @param currencyOrNil The ISO4217 currency code. Example: USD * @param currencyOrNil The ISO4217 currency code. Example: USD
* @param purchaseSucceededOrNil Was the purchase succesful or unsuccesful * @param purchaseSucceededOrNil Was the purchase succesful or unsuccesful
* @param itemNameOrNil The human-readable form of the item's name. Example: * @param itemNameOrNil The human-readable form of the item's name. Example:
* @param itemIdOrNil The machine-readable, unique item identifier Example: SKU
* @param itemTypeOrNil The type, or genre of the item. Example: Song * @param itemTypeOrNil The type, or genre of the item. Example: Song
* @param itemIdOrNil The machine-readable, unique item identifier Example: SKU
* @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase. * @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase.
*/ */
+ (void)logPurchaseWithPrice:(nullable NSDecimalNumber *)itemPriceOrNil + (void)logPurchaseWithPrice:(nullable NSDecimalNumber *)itemPriceOrNil
@@ -97,7 +101,7 @@ NS_ASSUME_NONNULL_BEGIN
* @param levelNameOrNil The name of the level completed, E.G. "1" or "Training" * @param levelNameOrNil The name of the level completed, E.G. "1" or "Training"
* @param scoreOrNil The score the user completed the level with. * @param scoreOrNil The score the user completed the level with.
* @param levelCompletedSuccesfullyOrNil A boolean representing whether or not the level was completed succesfully. * @param levelCompletedSuccesfullyOrNil A boolean representing whether or not the level was completed succesfully.
* @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase. * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
*/ */
+ (void)logLevelEnd:(nullable NSString *)levelNameOrNil + (void)logLevelEnd:(nullable NSString *)levelNameOrNil
score:(nullable NSNumber *)scoreOrNil score:(nullable NSNumber *)scoreOrNil
@@ -114,7 +118,7 @@ NS_ASSUME_NONNULL_BEGIN
* @param itemNameOrNil The human-readable form of the item's name. Example: * @param itemNameOrNil The human-readable form of the item's name. Example:
* @param itemTypeOrNil The type, or genre of the item. Example: Song * @param itemTypeOrNil The type, or genre of the item. Example: Song
* @param itemIdOrNil The machine-readable, unique item identifier Example: SKU * @param itemIdOrNil The machine-readable, unique item identifier Example: SKU
* @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase. * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
*/ */
+ (void)logAddToCartWithPrice:(nullable NSDecimalNumber *)itemPriceOrNil + (void)logAddToCartWithPrice:(nullable NSDecimalNumber *)itemPriceOrNil
currency:(nullable NSString *)currencyOrNil currency:(nullable NSString *)currencyOrNil
@@ -131,7 +135,7 @@ NS_ASSUME_NONNULL_BEGIN
* @param totalPriceOrNil The total price of the cart. * @param totalPriceOrNil The total price of the cart.
* @param currencyOrNil The ISO4217 currency code. Example: USD * @param currencyOrNil The ISO4217 currency code. Example: USD
* @param itemCountOrNil The number of items in the cart. * @param itemCountOrNil The number of items in the cart.
* @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase. * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
*/ */
+ (void)logStartCheckoutWithPrice:(nullable NSDecimalNumber *)totalPriceOrNil + (void)logStartCheckoutWithPrice:(nullable NSDecimalNumber *)totalPriceOrNil
currency:(nullable NSString *)currencyOrNil currency:(nullable NSString *)currencyOrNil
@@ -184,7 +188,7 @@ NS_ASSUME_NONNULL_BEGIN
* the name of the event, since this is how the event will appear in Answers. * the name of the event, since this is how the event will appear in Answers.
* *
* @param eventName The human-readable name for the event. * @param eventName The human-readable name for the event.
* @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase. Attribute keys * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. Attribute keys
* must be <code>NSString</code> and and values must be <code>NSNumber</code> or <code>NSString</code>. * must be <code>NSString</code> and and values must be <code>NSNumber</code> or <code>NSString</code>.
* @discussion How we treat <code>NSNumbers</code>: * @discussion How we treat <code>NSNumbers</code>:
* We will provide information about the distribution of values over time. * We will provide information about the distribution of values over time.

View File

@@ -181,6 +181,21 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
- (void)recordCustomExceptionName:(NSString *)name reason:(nullable NSString *)reason frameArray:(CLS_GENERIC_NSARRAY(CLSStackFrame *) *)frameArray; - (void)recordCustomExceptionName:(NSString *)name reason:(nullable NSString *)reason frameArray:(CLS_GENERIC_NSARRAY(CLSStackFrame *) *)frameArray;
/**
*
* This allows you to record a non-fatal event, described by an NSError object. These events will be grouped and
* displayed similarly to crashes. Keep in mind that this method can be expensive. Also, the total number of
* NSErrors that can be recorded during your app's life-cycle is limited by a fixed-size circular buffer. If the
* buffer is overrun, the oldest data is dropped. Errors are relayed to Crashlytics on a subsequent launch
* of your application.
*
* You can also use the -recordError:withAdditionalUserInfo: to include additional context not represented
* by the NSError instance itself.
*
**/
- (void)recordError:(NSError *)error;
- (void)recordError:(NSError *)error withAdditionalUserInfo:(nullable CLS_GENERIC_NSDICTIONARY(NSString *, id) *)userInfo;
- (void)logEvent:(NSString *)eventName CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:"); - (void)logEvent:(NSString *)eventName CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");
- (void)logEvent:(NSString *)eventName attributes:(nullable NSDictionary *) attributes CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:"); - (void)logEvent:(NSString *)eventName attributes:(nullable NSDictionary *) attributes CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");
+ (void)logEvent:(NSString *)eventName CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:"); + (void)logEvent:(NSString *)eventName CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");

View File

@@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>BuildMachineOSBuild</key> <key>BuildMachineOSBuild</key>
<string>14E46</string> <string>14F1021</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>English</string> <string>English</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
@@ -17,25 +17,29 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>3.3.4</string> <string>3.6.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>82</string> <string>99</string>
<key>DTCompiler</key> <key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string> <string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key> <key>DTPlatformBuild</key>
<string>6E35b</string> <string>7B91b</string>
<key>DTPlatformVersion</key> <key>DTPlatformVersion</key>
<string>GM</string> <string>GM</string>
<key>DTSDKBuild</key> <key>DTSDKBuild</key>
<string>14D125</string> <string>15A278</string>
<key>DTSDKName</key> <key>DTSDKName</key>
<string>macosx10.10</string> <string>macosx10.11</string>
<key>DTXcode</key> <key>DTXcode</key>
<string>0640</string> <string>0710</string>
<key>DTXcodeBuild</key> <key>DTXcodeBuild</key>
<string>6E35b</string> <string>7B91b</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2015 Crashlytics, Inc. All rights reserved.</string> <string>Copyright © 2015 Crashlytics, Inc. All rights reserved.</string>
<key>UIDeviceFamily</key> <key>UIDeviceFamily</key>

View File

@@ -11,8 +11,8 @@ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
DIR="\"${DIR}" DIR="\"${DIR}"
PATH_SEP="/" PATH_SEP="/"
VALIDATE_COMMAND="uploadDSYM\" $@ validate" VALIDATE_COMMAND="uploadDSYM\" $@ validate run-script"
UPLOAD_COMMAND="uploadDSYM\" $@" UPLOAD_COMMAND="uploadDSYM\" $@ run-script"
# Ensure params are as expected, run in sync mode to validate # Ensure params are as expected, run in sync mode to validate
eval $DIR$PATH_SEP$VALIDATE_COMMAND eval $DIR$PATH_SEP$VALIDATE_COMMAND

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,7 +2,19 @@
// FABAttributes.h // FABAttributes.h
// Fabric // Fabric
// //
// Copyright (c) 2015 Twitter. All rights reserved. // Copyright (C) 2015 Twitter, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// //
#pragma once #pragma once

View File

@@ -1,7 +1,20 @@
// //
// Fabric.h // Fabric.h
// Fabric
// //
// Copyright (c) 2015 Twitter. All rights reserved. // Copyright (C) 2015 Twitter, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>

View File

@@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>BuildMachineOSBuild</key> <key>BuildMachineOSBuild</key>
<string>14E46</string> <string>14F1021</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>en</string> <string>en</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.5.5</string> <string>1.6.4</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleSupportedPlatforms</key> <key>CFBundleSupportedPlatforms</key>
@@ -25,11 +25,11 @@
<string>MacOSX</string> <string>MacOSX</string>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>30</string> <string>45</string>
<key>DTCompiler</key> <key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string> <string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key> <key>DTPlatformBuild</key>
<string>7A220</string> <string>7B91b</string>
<key>DTPlatformVersion</key> <key>DTPlatformVersion</key>
<string>GM</string> <string>GM</string>
<key>DTSDKBuild</key> <key>DTSDKBuild</key>
@@ -37,9 +37,9 @@
<key>DTSDKName</key> <key>DTSDKName</key>
<string>macosx10.11</string> <string>macosx10.11</string>
<key>DTXcode</key> <key>DTXcode</key>
<string>0700</string> <string>0710</string>
<key>DTXcodeBuild</key> <key>DTXcodeBuild</key>
<string>7A220</string> <string>7B91b</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2015 Twitter. All rights reserved.</string> <string>Copyright © 2015 Twitter. All rights reserved.</string>
<key>UIDeviceFamily</key> <key>UIDeviceFamily</key>

View File

@@ -11,8 +11,8 @@ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
DIR="\"${DIR}" DIR="\"${DIR}"
PATH_SEP="/" PATH_SEP="/"
VALIDATE_COMMAND="uploadDSYM\" $@ validate" VALIDATE_COMMAND="uploadDSYM\" $@ validate run-script"
UPLOAD_COMMAND="uploadDSYM\" $@" UPLOAD_COMMAND="uploadDSYM\" $@ run-script"
# Ensure params are as expected, run in sync mode to validate # Ensure params are as expected, run in sync mode to validate
eval $DIR$PATH_SEP$VALIDATE_COMMAND eval $DIR$PATH_SEP$VALIDATE_COMMAND

Binary file not shown.

2
External/Pearl vendored

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# #
# TROUBLESHOOTING # TROUBLESHOOTING
# - To enable verbose algorithm/implementation debugging, use ./build -DDEBUG
# - If you see 'undefined reference to `AES_encrypt'', # - If you see 'undefined reference to `AES_encrypt'',
# make sure you have openssl installed. # make sure you have openssl installed.
# If libcrypto.a is in a non-standard directory, try ./build -L[your-lib-dir] # If libcrypto.a is in a non-standard directory, try ./build -L[your-lib-dir]

View File

@@ -8,6 +8,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <arpa/inet.h>
#include "mpw-types.h" #include "mpw-types.h"
#include "mpw-util.h" #include "mpw-util.h"

View File

@@ -8,6 +8,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <arpa/inet.h>
#include "mpw-types.h" #include "mpw-types.h"
#include "mpw-util.h" #include "mpw-util.h"

View File

@@ -8,6 +8,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <arpa/inet.h>
#include "mpw-types.h" #include "mpw-types.h"
#include "mpw-util.h" #include "mpw-util.h"

View File

@@ -8,6 +8,7 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <arpa/inet.h>
#include "mpw-types.h" #include "mpw-types.h"
#include "mpw-util.h" #include "mpw-util.h"

View File

@@ -16,6 +16,7 @@
#include <bcrypt/ow-crypt.h> #include <bcrypt/ow-crypt.h>
#include "mpw-algorithm.h" #include "mpw-algorithm.h"
#include "mpw-util.h"
#define MP_N 32768 #define MP_N 32768
#define MP_r 8 #define MP_r 8

View File

@@ -13,8 +13,6 @@
#include <histedit.h> #include <histedit.h>
#endif #endif
#define ftl(...) do { fprintf( stderr, __VA_ARGS__ ); exit(2); } while (0)
#include "mpw-algorithm.h" #include "mpw-algorithm.h"
#include "mpw-util.h" #include "mpw-util.h"
@@ -25,9 +23,9 @@
static void usage() { static void usage() {
fprintf( stderr, "Usage: mpw [-u name] [-t type] [-c counter] [-V version] [-v variant] [-C context] [-h] site\n\n" ); fprintf( stderr, "Usage: mpw [-u name] [-t type] [-c counter] [-a algorithm] [-V variant] [-C context] [-v|-q] [-h] site\n\n" );
fprintf( stderr, " -u name Specify the full name of the user.\n" fprintf( stderr, " -u name Specify the full name of the user.\n"
" Defaults to %s in env.\n\n", MP_env_fullname ); " Defaults to %s in env or prompts.\n\n", MP_env_fullname );
fprintf( stderr, " -t type Specify the password's template.\n" fprintf( stderr, " -t type Specify the password's template.\n"
" Defaults to %s in env or 'long' for password, 'name' for login.\n" " Defaults to %s in env or 'long' for password, 'name' for login.\n"
" x, max, maximum | 20 characters, contains symbols.\n" " x, max, maximum | 20 characters, contains symbols.\n"
@@ -40,23 +38,27 @@ static void usage() {
" p, phrase | 20 character sentence.\n\n", MP_env_sitetype ); " p, phrase | 20 character sentence.\n\n", MP_env_sitetype );
fprintf( stderr, " -c counter The value of the counter.\n" fprintf( stderr, " -c counter The value of the counter.\n"
" Defaults to %s in env or 1.\n\n", MP_env_sitecounter ); " Defaults to %s in env or 1.\n\n", MP_env_sitecounter );
fprintf( stderr, " -V version The algorithm version to use.\n" fprintf( stderr, " -a version The algorithm version to use.\n"
" Defaults to %s in env or %d.\n\n", MP_env_algorithm, MPAlgorithmVersionCurrent ); " Defaults to %s in env or %d.\n\n", MP_env_algorithm, MPAlgorithmVersionCurrent );
fprintf( stderr, " -v variant The kind of content to generate.\n" fprintf( stderr, " -V variant The kind of content to generate.\n"
" Defaults to 'password'.\n" " Defaults to 'password'.\n"
" p, password | The password to log in with.\n" " p, password | The password to log in with.\n"
" l, login | The username to log in as.\n" " l, login | The username to log in as.\n"
" a, answer | The answer to a security question.\n\n" ); " a, answer | The answer to a security question.\n\n" );
fprintf( stderr, " -C context A variant-specific context.\n" fprintf( stderr, " -C context A variant-specific context.\n"
" Defaults to empty.\n" " Defaults to empty.\n"
" -v p, password | Doesn't currently use a context.\n" " -V p, password | Doesn't currently use a context.\n"
" -v l, login | Doesn't currently use a context.\n" " -V l, login | Doesn't currently use a context.\n"
" -v a, answer | Empty for a universal site answer or\n" " -V a, answer | Empty for a universal site answer or\n"
" | the most significant word(s) of the question.\n\n" ); " | the most significant word(s) of the question.\n\n" );
fprintf( stderr, " -v Increase output verbosity (can be repeated).\n\n" );
fprintf( stderr, " -q Decrease output verbosity (can be repeated).\n\n" );
fprintf( stderr, " ENVIRONMENT\n\n" fprintf( stderr, " ENVIRONMENT\n\n"
" MP_FULLNAME | The full name of the user.\n" " %-14s | The full name of the user (see -u).\n"
" MP_SITETYPE | The default password template.\n" " %-14s | The default password template (see -t).\n"
" MP_SITECOUNTER | The default counter value.\n\n" ); " %-14s | The default counter value (see -c).\n"
" %-14s | The default algorithm version (see -a).\n\n",
MP_env_fullname, MP_env_sitetype, MP_env_sitecounter, MP_env_algorithm );
exit( 0 ); exit( 0 );
} }
@@ -111,7 +113,7 @@ int main(int argc, char *const argv[]) {
ftl( "Invalid %s: %s\n", MP_env_algorithm, algorithmVersionString ); ftl( "Invalid %s: %s\n", MP_env_algorithm, algorithmVersionString );
// Read the options. // Read the options.
for (int opt; (opt = getopt( argc, argv, "u:P:t:c:v:V:C:h" )) != -1;) for (int opt; (opt = getopt( argc, argv, "u:P:t:c:V:a:C:vqh" )) != -1;)
switch (opt) { switch (opt) {
case 'u': case 'u':
fullName = optarg; fullName = optarg;
@@ -127,16 +129,22 @@ int main(int argc, char *const argv[]) {
case 'c': case 'c':
siteCounterString = optarg; siteCounterString = optarg;
break; break;
case 'v': case 'V':
siteVariantString = optarg; siteVariantString = optarg;
break; break;
case 'V': case 'a':
if (sscanf( optarg, "%u", &algorithmVersion ) != 1) if (sscanf( optarg, "%u", &algorithmVersion ) != 1)
ftl( "Not a version: %s\n", optarg ); ftl( "Not a version: %s\n", optarg );
break; break;
case 'C': case 'C':
siteContextString = optarg; siteContextString = optarg;
break; break;
case 'v':
++mpw_verbosity;
break;
case 'q':
--mpw_verbosity;
break;
case 'h': case 'h':
usage(); usage();
break; break;

View File

@@ -6,21 +6,50 @@
// Copyright (c) 2014 Lyndir. All rights reserved. // Copyright (c) 2014 Lyndir. All rights reserved.
// //
#include <stdio.h>
#include <stdint.h> #include <stdint.h>
//// Logging. //// Logging.
#ifdef DEBUG #ifndef trc
#ifndef trc int mpw_verbosity;
#define trc(...) fprintf( stderr, __VA_ARGS__ ) #define trc_level 3
#endif #define trc(...) \
#else if (mpw_verbosity >= 3) \
#ifndef trc fprintf( stderr, __VA_ARGS__ )
#define trc(...) do {} while (0) #endif
#endif #ifndef dbg
#define dbg_level 2
#define dbg(...) \
if (mpw_verbosity >= 2) \
fprintf( stderr, __VA_ARGS__ )
#endif
#ifndef inf
#define inf_level 1
#define inf(...) \
if (mpw_verbosity >= 1) \
fprintf( stderr, __VA_ARGS__ )
#endif
#ifndef wrn
#define wrn_level 0
#define wrn(...) \
if (mpw_verbosity >= 0) \
fprintf( stderr, __VA_ARGS__ )
#endif
#ifndef err
#define err_level -1
#define err(...) \
if (mpw_verbosity >= -1) \
fprintf( stderr, __VA_ARGS__ )
#endif #endif
#ifndef ftl #ifndef ftl
#define ftl(...) do { fprintf( stderr, __VA_ARGS__ ); abort(); } while (0) #define ftl_level -2
#define ftl(...) \
do { \
if (mpw_verbosity >= -2) \
fprintf( stderr, __VA_ARGS__ ); \
exit( 2 ); \
} while (0)
#endif #endif
//// Buffers and memory. //// Buffers and memory.

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword</artifactId> <artifactId>masterpassword</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</parent> </parent>
<name>Master Password Algorithm Implementation</name> <name>Master Password Algorithm Implementation</name>

View File

@@ -16,12 +16,12 @@ import org.jetbrains.annotations.Contract;
*/ */
public enum MPSiteType { public enum MPSiteType {
GeneratedMaximum( "20 characters, contains symbols.", // GeneratedMaximum( "Max", "20 characters, contains symbols.", //
ImmutableList.of( "x", "max", "maximum" ), // ImmutableList.of( "x", "max", "maximum" ), //
ImmutableList.of( new MPTemplate( "anoxxxxxxxxxxxxxxxxx" ), new MPTemplate( "axxxxxxxxxxxxxxxxxno" ) ), // ImmutableList.of( new MPTemplate( "anoxxxxxxxxxxxxxxxxx" ), new MPTemplate( "axxxxxxxxxxxxxxxxxno" ) ), //
MPSiteTypeClass.Generated, 0x0 ), MPSiteTypeClass.Generated, 0x0 ),
GeneratedLong( "Copy-friendly, 14 characters, contains symbols.", // GeneratedLong( "Long", "Copy-friendly, 14 characters, contains symbols.", //
ImmutableList.of( "l", "long" ), // ImmutableList.of( "l", "long" ), //
ImmutableList.of( new MPTemplate( "CvcvnoCvcvCvcv" ), new MPTemplate( "CvcvCvcvnoCvcv" ), ImmutableList.of( new MPTemplate( "CvcvnoCvcvCvcv" ), new MPTemplate( "CvcvCvcvnoCvcv" ),
new MPTemplate( "CvcvCvcvCvcvno" ), new MPTemplate( "CvccnoCvcvCvcv" ), new MPTemplate( "CvcvCvcvCvcvno" ), new MPTemplate( "CvccnoCvcvCvcv" ),
@@ -36,49 +36,50 @@ public enum MPSiteType {
new MPTemplate( "CvccCvcvCvccno" ) ), // new MPTemplate( "CvccCvcvCvccno" ) ), //
MPSiteTypeClass.Generated, 0x1 ), MPSiteTypeClass.Generated, 0x1 ),
GeneratedMedium( "Copy-friendly, 8 characters, contains symbols.", // GeneratedMedium( "Medium", "Copy-friendly, 8 characters, contains symbols.", //
ImmutableList.of( "m", "med", "medium" ), // ImmutableList.of( "m", "med", "medium" ), //
ImmutableList.of( new MPTemplate( "CvcnoCvc" ), new MPTemplate( "CvcCvcno" ) ), // ImmutableList.of( new MPTemplate( "CvcnoCvc" ), new MPTemplate( "CvcCvcno" ) ), //
MPSiteTypeClass.Generated, 0x2 ), MPSiteTypeClass.Generated, 0x2 ),
GeneratedBasic( "8 characters, no symbols.", // GeneratedBasic( "Basic", "8 characters, no symbols.", //
ImmutableList.of( "b", "basic" ), // ImmutableList.of( "b", "basic" ), //
ImmutableList.of( new MPTemplate( "aaanaaan" ), new MPTemplate( "aannaaan" ), new MPTemplate( "aaannaaa" ) ), // ImmutableList.of( new MPTemplate( "aaanaaan" ), new MPTemplate( "aannaaan" ), new MPTemplate( "aaannaaa" ) ), //
MPSiteTypeClass.Generated, 0x3 ), MPSiteTypeClass.Generated, 0x3 ),
GeneratedShort( "Copy-friendly, 4 characters, no symbols.", // GeneratedShort( "Short", "Copy-friendly, 4 characters, no symbols.", //
ImmutableList.of( "s", "short" ), // ImmutableList.of( "s", "short" ), //
ImmutableList.of( new MPTemplate( "Cvcn" ) ), // ImmutableList.of( new MPTemplate( "Cvcn" ) ), //
MPSiteTypeClass.Generated, 0x4 ), MPSiteTypeClass.Generated, 0x4 ),
GeneratedPIN( "4 numbers.", // GeneratedPIN( "PIN", "4 numbers.", //
ImmutableList.of( "i", "pin" ), // ImmutableList.of( "i", "pin" ), //
ImmutableList.of( new MPTemplate( "nnnn" ) ), // ImmutableList.of( new MPTemplate( "nnnn" ) ), //
MPSiteTypeClass.Generated, 0x5 ), MPSiteTypeClass.Generated, 0x5 ),
GeneratedName( "9 letter name.", // GeneratedName( "Name", "9 letter name.", //
ImmutableList.of( "n", "name" ), // ImmutableList.of( "n", "name" ), //
ImmutableList.of( new MPTemplate( "cvccvcvcv" ) ), // ImmutableList.of( new MPTemplate( "cvccvcvcv" ) ), //
MPSiteTypeClass.Generated, 0xE ), MPSiteTypeClass.Generated, 0xE ),
GeneratedPhrase( "20 character sentence.", // GeneratedPhrase( "Phrase", "20 character sentence.", //
ImmutableList.of( "p", "phrase" ), // ImmutableList.of( "p", "phrase" ), //
ImmutableList.of( new MPTemplate( "cvcc cvc cvccvcv cvc" ), new MPTemplate( "cvc cvccvcvcv cvcv" ), ImmutableList.of( new MPTemplate( "cvcc cvc cvccvcv cvc" ), new MPTemplate( "cvc cvccvcvcv cvcv" ),
new MPTemplate( "cv cvccv cvc cvcvccv" ) ), // new MPTemplate( "cv cvccv cvc cvcvccv" ) ), //
MPSiteTypeClass.Generated, 0xF ), MPSiteTypeClass.Generated, 0xF ),
StoredPersonal( "AES-encrypted, exportable.", // StoredPersonal( "Personal", "AES-encrypted, exportable.", //
ImmutableList.of( "personal" ), // ImmutableList.of( "personal" ), //
ImmutableList.<MPTemplate>of(), // ImmutableList.<MPTemplate>of(), //
MPSiteTypeClass.Stored, 0x0, MPSiteFeature.ExportContent ), MPSiteTypeClass.Stored, 0x0, MPSiteFeature.ExportContent ),
StoredDevicePrivate( "AES-encrypted, not exported.", // StoredDevicePrivate( "Device", "AES-encrypted, not exported.", //
ImmutableList.of( "device" ), // ImmutableList.of( "device" ), //
ImmutableList.<MPTemplate>of(), // ImmutableList.<MPTemplate>of(), //
MPSiteTypeClass.Stored, 0x1, MPSiteFeature.DevicePrivate ); MPSiteTypeClass.Stored, 0x1, MPSiteFeature.DevicePrivate );
static final Logger logger = Logger.get( MPSiteType.class ); static final Logger logger = Logger.get( MPSiteType.class );
private final String shortName;
private final String description; private final String description;
private final List<String> options; private final List<String> options;
private final List<MPTemplate> templates; private final List<MPTemplate> templates;
@@ -86,9 +87,10 @@ public enum MPSiteType {
private final int typeIndex; private final int typeIndex;
private final Set<MPSiteFeature> typeFeatures; private final Set<MPSiteFeature> typeFeatures;
MPSiteType(final String description, final List<String> options, final List<MPTemplate> templates, final MPSiteTypeClass typeClass, MPSiteType(final String shortName, final String description, final List<String> options, final List<MPTemplate> templates,
final int typeIndex, final MPSiteFeature... typeFeatures) { final MPSiteTypeClass typeClass, final int typeIndex, final MPSiteFeature... typeFeatures) {
this.shortName = shortName;
this.description = description; this.description = description;
this.options = options; this.options = options;
this.templates = templates; this.templates = templates;
@@ -102,6 +104,10 @@ public enum MPSiteType {
this.typeFeatures = typeFeaturesBuilder.build(); this.typeFeatures = typeFeaturesBuilder.build();
} }
public String getShortName() {
return shortName;
}
public String getDescription() { public String getDescription() {
return description; return description;

View File

@@ -17,9 +17,11 @@ public abstract class MasterKey {
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
private static final Logger logger = Logger.get( MasterKey.class ); private static final Logger logger = Logger.get( MasterKey.class );
private static boolean allowNativeByDefault = true;
@Nonnull @Nonnull
private final String fullName; private final String fullName;
private boolean allowNative = allowNativeByDefault;
@Nullable @Nullable
private byte[] masterKey; private byte[] masterKey;
@@ -46,6 +48,23 @@ public abstract class MasterKey {
throw new UnsupportedOperationException( "Unsupported version: " + version ); throw new UnsupportedOperationException( "Unsupported version: " + version );
} }
public static boolean isAllowNativeByDefault() {
return allowNativeByDefault;
}
/**
* Native libraries are useful for speeding up the performance of cryptographical functions.
* Sometimes, however, we may prefer to use Java-only code.
* For instance, for auditability / trust or because the native code doesn't work on our CPU/platform.
* <p/>
* This setter affects the default setting for any newly created {@link MasterKey}s.
*
* @param allowNative false to disallow the use of native libraries.
*/
public static void setAllowNativeByDefault(final boolean allowNative) {
allowNativeByDefault = allowNative;
}
protected MasterKey(@NotNull final String fullName) { protected MasterKey(@NotNull final String fullName) {
this.fullName = fullName; this.fullName = fullName;
@@ -63,6 +82,15 @@ public abstract class MasterKey {
return fullName; return fullName;
} }
public boolean isAllowNative() {
return allowNative;
}
public MasterKey setAllowNative(final boolean allowNative) {
this.allowNative = allowNative;
return this;
}
@Nonnull @Nonnull
protected byte[] getKey() { protected byte[] getKey() {

View File

@@ -65,8 +65,15 @@ public class MasterKeyV0 extends MasterKey {
mpBytesBuf.get( mpBytes, 0, mpBytes.length ); mpBytesBuf.get( mpBytes, 0, mpBytes.length );
Arrays.fill( mpBytesBuf.array(), (byte) 0 ); Arrays.fill( mpBytesBuf.array(), (byte) 0 );
return scrypt( masterKeySalt, mpBytes );
}
protected byte[] scrypt(final byte[] masterKeySalt, final byte[] mpBytes) {
try { try {
if (isAllowNative())
return SCrypt.scrypt( mpBytes, masterKeySalt, MP_N, MP_r, MP_p, MP_dkLen ); return SCrypt.scrypt( mpBytes, masterKeySalt, MP_N, MP_r, MP_p, MP_dkLen );
else
return SCrypt.scryptJ( mpBytes, masterKeySalt, MP_N, MP_r, MP_p, MP_dkLen );
} }
catch (GeneralSecurityException e) { catch (GeneralSecurityException e) {
logger.bug( e ); logger.bug( e );

View File

@@ -46,17 +46,8 @@ public class MasterKeyV3 extends MasterKeyV2 {
ByteBuffer mpBytesBuf = MP_charset.encode( CharBuffer.wrap( masterPassword ) ); ByteBuffer mpBytesBuf = MP_charset.encode( CharBuffer.wrap( masterPassword ) );
byte[] mpBytes = new byte[mpBytesBuf.remaining()]; byte[] mpBytes = new byte[mpBytesBuf.remaining()];
mpBytesBuf.get( mpBytes, 0, mpBytes.length ); mpBytesBuf.get( mpBytes, 0, mpBytes.length );
Arrays.fill( mpBytesBuf.array(), (byte)0 ); Arrays.fill( mpBytesBuf.array(), (byte) 0 );
try { return scrypt( masterKeySalt, mpBytes );
return SCrypt.scrypt( mpBytes, masterKeySalt, MP_N, MP_r, MP_p, MP_dkLen );
}
catch (GeneralSecurityException e) {
logger.bug( e );
return null;
}
finally {
Arrays.fill( mpBytes, (byte) 0 );
}
} }
} }

View File

@@ -11,14 +11,15 @@
<application <application
android:icon="@drawable/icon" android:icon="@drawable/icon"
android:label="@string/app_name" android:label="@string/app_name"
android:allowBackup="true"> android:allowBackup="true"
<activity android:name=".TestActivity" android:theme="@style/MPTheme"> android:debuggable="true">
<activity android:name=".EmergencyActivity" android:theme="@style/MPTheme">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".EmergencyActivity" android:theme="@style/MPTheme" /> <activity android:name=".TestActivity" android:theme="@style/MPTheme" />
</application> </application>
</manifest> </manifest>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword</artifactId> <artifactId>masterpassword</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</parent> </parent>
<name>Master Password Android</name> <name>Master Password Android</name>
@@ -67,6 +67,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId> <artifactId>maven-jarsigner-plugin</artifactId>
<version>1.4</version>
<executions> <executions>
<execution> <execution>
<id>signing</id> <id>signing</id>
@@ -104,13 +105,13 @@
<dependency> <dependency>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword-algorithm</artifactId> <artifactId>masterpassword-algorithm</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword-tests</artifactId> <artifactId>masterpassword-tests</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</dependency> </dependency>
<!-- EXTERNAL DEPENDENCIES --> <!-- EXTERNAL DEPENDENCIES -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true" android:fillViewport="true"
@@ -17,6 +18,13 @@
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1" /> android:layout_weight="1" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:importantForAccessibility="no"
android:src="@drawable/img_identity" />
<EditText <EditText
android:id="@+id/fullNameField" android:id="@+id/fullNameField"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -26,14 +34,14 @@
android:hint="@string/fullName_hint" android:hint="@string/fullName_hint"
android:gravity="center" android:gravity="center"
android:textColor="#FFFFFF" android:textColor="#FFFFFF"
android:textSize="26sp" /> android:textSize="16sp" />
<CheckBox <CheckBox
android:id="@+id/rememberFullNameField" android:id="@+id/rememberFullNameField"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:nextFocusForward="@+id/rememberPasswordField" android:nextFocusForward="@+id/rememberPasswordField"
android:textSize="14sp" android:textSize="12sp"
android:textColor="@android:color/tertiary_text_dark" android:textColor="@android:color/tertiary_text_dark"
android:text="@string/remember" /> android:text="@string/remember" />
@@ -46,16 +54,24 @@
android:hint="@string/masterPassword_hint" android:hint="@string/masterPassword_hint"
android:gravity="center" android:gravity="center"
android:textColor="#FFFFFF" android:textColor="#FFFFFF"
android:textSize="18sp" /> android:textSize="16sp" />
<CheckBox <CheckBox
android:id="@id/rememberPasswordField" android:id="@id/rememberPasswordField"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="14sp" android:textSize="12sp"
android:textColor="@android:color/tertiary_text_dark" android:textColor="@android:color/tertiary_text_dark"
android:text="@string/forgetOnClose" /> android:text="@string/forgetOnClose" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="8dp"
android:importantForAccessibility="no"
android:src="@drawable/img_key" />
<EditText <EditText
android:id="@id/siteNameField" android:id="@id/siteNameField"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -65,7 +81,7 @@
android:hint="@string/siteName_hint" android:hint="@string/siteName_hint"
android:gravity="center" android:gravity="center"
android:textColor="#FFFFFF" android:textColor="#FFFFFF"
android:textSize="18sp" /> android:textSize="16sp" />
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -76,8 +92,9 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_margin="20dp" android:visibility="invisible"
android:indeterminate="true" /> android:indeterminate="true"
tools:visibility="visible" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -89,12 +106,12 @@
android:id="@id/sitePasswordField" android:id="@id/sitePasswordField"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:nextFocusForward="@+id/siteTypeField" android:nextFocusForward="@+id/siteTypeButton"
android:gravity="center" android:gravity="center"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:textColor="#FFFFFF" android:textColor="#FFFFFF"
android:textSize="32sp" android:textSize="28sp"
android:text="LuxdZozvDuma4[" tools:text="LuxdZozvDuma4["
android:onClick="copySitePassword" /> android:onClick="copySitePassword" />
<TextView <TextView
@@ -104,7 +121,7 @@
android:labelFor="@id/sitePasswordField" android:labelFor="@id/sitePasswordField"
android:gravity="center" android:gravity="center"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:textSize="14sp" android:textSize="12sp"
android:textColor="@android:color/tertiary_text_dark" android:textColor="@android:color/tertiary_text_dark"
android:text="@string/sitePassword_hint" /> android:text="@string/sitePassword_hint" />
@@ -115,55 +132,137 @@
android:id="@+id/maskPasswordField" android:id="@+id/maskPasswordField"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textSize="14sp" android:textSize="12sp"
android:textColor="@android:color/tertiary_text_dark" android:textColor="@android:color/tertiary_text_dark"
android:text="@string/maskPassword" /> android:text="@string/maskPassword" />
<Spinner <ImageView
android:id="@id/siteTypeField"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:nextFocusForward="@+id/counterField" android:layout_marginTop="20dp"
android:gravity="center" /> android:layout_marginBottom="8dp"
android:importantForAccessibility="no"
android:src="@drawable/divider" />
<EditText <LinearLayout
android:id="@id/counterField"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:nextFocusForward="@+id/siteVersionField" style="?android:buttonBarStyle"
android:orientation="horizontal"
android:gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<Button
android:id="@id/siteTypeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
style="?android:buttonBarButtonStyle"
android:nextFocusForward="@+id/counterField"
android:gravity="center" android:gravity="center"
android:inputType="text|textNoSuggestions"
android:textColor="#FFFFFF" android:textColor="#FFFFFF"
android:textSize="18sp" android:textSize="16sp"
android:text="1" /> android:drawableStart="@drawable/icon_key"
android:drawablePadding="8dp"
android:background="@android:color/transparent"
tools:text="Long" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:labelFor="@id/counterField" android:labelFor="@id/siteTypeButton"
android:gravity="center" android:gravity="center"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:textSize="14sp" android:textSize="12sp"
android:textColor="@android:color/tertiary_text_dark"
android:text="@string/siteType_hint" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<Button
android:id="@id/counterField"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
style="?android:buttonBarButtonStyle"
android:nextFocusForward="@+id/siteVersionButton"
android:gravity="center"
android:textColor="#FFFFFF"
android:textSize="16sp"
android:drawableStart="@drawable/icon_plus"
android:drawablePadding="8dp"
android:background="@android:color/transparent"
tools:text="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:labelFor="@id/siteVersionButton"
android:gravity="center"
android:background="@android:color/transparent"
android:textSize="12sp"
android:textColor="@android:color/tertiary_text_dark" android:textColor="@android:color/tertiary_text_dark"
android:text="@string/siteCounter_hint" /> android:text="@string/siteCounter_hint" />
<Spinner </LinearLayout>
android:id="@id/siteVersionField"
android:layout_width="match_parent" <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:nextFocusForward="@id/rememberFullNameField" android:orientation="vertical"
android:gravity="center" /> android:gravity="center">
<Button
android:id="@id/siteVersionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
style="?android:buttonBarButtonStyle"
android:nextFocusForward="@+id/rememberFullNameField"
android:gravity="center"
android:textColor="#FFFFFF"
android:textSize="16sp"
android:drawableStart="@drawable/icon_gears"
android:drawablePadding="8dp"
android:background="@android:color/transparent"
tools:text="3" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:labelFor="@id/siteVersionField" android:labelFor="@id/siteVersionButton"
android:gravity="center" android:gravity="center"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:textSize="14sp" android:textSize="12sp"
android:textColor="@android:color/tertiary_text_dark" android:textColor="@android:color/tertiary_text_dark"
android:text="@string/siteVersion_hint" /> android:text="@string/siteVersion_hint" />
</LinearLayout>
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textSize="16sp"
android:text="@string/btn_tests"
android:onClick="integrityTests"
android:background="@android:color/transparent" />
<View <View
android:layout_width="1dp" android:layout_width="1dp"
android:layout_height="0dp" android:layout_height="0dp"

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true" android:fillViewport="true"
@@ -17,22 +18,31 @@
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1" /> android:layout_weight="1" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:importantForAccessibility="no"
android:src="@drawable/img_stats" />
<ProgressBar <ProgressBar
android:id="@+id/progressView" android:id="@+id/progressView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_margin="8dp" android:layout_margin="8dp"
style="@android:style/Widget.ProgressBar.Horizontal" /> tools:max="100"
tools:progress="80"
style="?android:progressBarStyleHorizontal" />
<TextView <TextView
android:id="@+id/statusView" android:id="@+id/statusView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:labelFor="@id/sitePasswordField"
android:gravity="center" android:gravity="center"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:textSize="14sp" android:textSize="12sp"
android:textColor="@android:color/secondary_text_dark" android:textColor="@android:color/tertiary_text_dark"
android:text="@string/tests_testing" /> android:text="@string/tests_testing" />
<TextView <TextView
@@ -53,8 +63,15 @@
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:enabled="false" android:enabled="false"
android:text="@string/tests_btn_testing" android:text="@string/tests_btn_testing"
android:onClick="onAction"/> android:onClick="onAction" />
<CheckBox
android:id="@+id/nativeKDFField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="@android:color/tertiary_text_dark"
android:text="@string/nativeKDF" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View File

@@ -8,15 +8,18 @@
<string name="masterPassword_hint">Your master password</string> <string name="masterPassword_hint">Your master password</string>
<string name="siteName_hint">eg. google.com</string> <string name="siteName_hint">eg. google.com</string>
<string name="sitePassword_hint">Tap to copy</string> <string name="sitePassword_hint">Tap to copy</string>
<string name="siteCounter_hint">Password #</string> <string name="siteType_hint">Type</string>
<string name="siteCounter_hint">Counter</string>
<string name="siteVersion_hint">Algorithm</string> <string name="siteVersion_hint">Algorithm</string>
<string name="empty" /> <string name="empty" />
<string name="btn_tests">Integrity Tests </string>
<string name="tests_unavailable">Test suite unavailable.</string> <string name="tests_unavailable">Test suite unavailable.</string>
<string name="tests_btn_unavailable">Exit</string> <string name="tests_btn_unavailable">Retest</string>
<string name="tests_testing">Testing device\'s password generation integrity…</string> <string name="tests_testing">Testing device\'s password generation integrity…</string>
<string name="tests_btn_testing">Please Stand By…</string> <string name="tests_btn_testing">Please Stand By…</string>
<string name="tests_failed">Incompatible device or OS.</string> <string name="tests_failed">Incompatible device or OS.</string>
<string name="tests_btn_failed">Exit</string> <string name="tests_btn_failed">Retest</string>
<string name="tests_passed">Integrity checks passed!</string> <string name="tests_passed">Integrity checks passed!</string>
<string name="tests_btn_passed">Continue</string> <string name="tests_btn_passed">Close</string>
<string name="nativeKDF">Use native key derivation</string>
</resources> </resources>

View File

@@ -1,6 +1,5 @@
package com.lyndir.masterpassword; package com.lyndir.masterpassword;
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.ifNotNullElse;
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf; import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
import android.app.*; import android.app.*;
@@ -17,9 +16,11 @@ import android.widget.*;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.InjectView; import butterknife.InjectView;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
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.lhunath.opal.system.logging.Logger; import com.lyndir.lhunath.opal.system.logging.Logger;
import java.text.MessageFormat;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -32,19 +33,10 @@ public class EmergencyActivity extends Activity {
private static final ClipData EMPTY_CLIP = new ClipData( new ClipDescription( "", new String[0] ), new ClipData.Item( "" ) ); private static final ClipData EMPTY_CLIP = new ClipData( new ClipDescription( "", new String[0] ), new ClipData.Item( "" ) );
private static final int PASSWORD_NOTIFICATION = 0; private static final int PASSWORD_NOTIFICATION = 0;
private final Preferences preferences = Preferences.get( this );
private final ListeningExecutorService executor = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor() ); private final ListeningExecutorService executor = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor() );
private final ValueChangedListener updateMasterKey = new ValueChangedListener() { private final ImmutableList<MPSiteType> allSiteTypes = ImmutableList.copyOf( MPSiteType.forClass( MPSiteTypeClass.Generated ) );
@Override private final ImmutableList<MasterKey.Version> allVersions = ImmutableList.copyOf( MasterKey.Version.values() );
void update() {
updateMasterKey();
}
};
private final ValueChangedListener updateSitePassword = new ValueChangedListener() {
@Override
void update() {
updateSitePassword();
}
};
private ListenableFuture<MasterKey> masterKeyFuture; private ListenableFuture<MasterKey> masterKeyFuture;
@@ -60,14 +52,14 @@ public class EmergencyActivity extends Activity {
@InjectView(R.id.siteNameField) @InjectView(R.id.siteNameField)
EditText siteNameField; EditText siteNameField;
@InjectView(R.id.siteTypeField) @InjectView(R.id.siteTypeButton)
Spinner siteTypeField; Button siteTypeButton;
@InjectView(R.id.counterField) @InjectView(R.id.counterField)
EditText counterField; Button siteCounterButton;
@InjectView(R.id.siteVersionField) @InjectView(R.id.siteVersionButton)
Spinner siteVersionField; Button siteVersionButton;
@InjectView(R.id.sitePasswordField) @InjectView(R.id.sitePasswordField)
Button sitePasswordField; Button sitePasswordField;
@@ -84,8 +76,9 @@ public class EmergencyActivity extends Activity {
@InjectView(R.id.maskPasswordField) @InjectView(R.id.maskPasswordField)
CheckBox maskPasswordField; CheckBox maskPasswordField;
private int hc_userName; private int id_userName;
private int hc_masterPassword; private int id_masterPassword;
private int id_version;
private String sitePassword; private String sitePassword;
public static void start(Context context) { public static void start(Context context) {
@@ -101,12 +94,58 @@ public class EmergencyActivity extends Activity {
setContentView( R.layout.activity_emergency ); setContentView( R.layout.activity_emergency );
ButterKnife.inject( this ); ButterKnife.inject( this );
fullNameField.setOnFocusChangeListener( updateMasterKey ); fullNameField.setOnFocusChangeListener( new ValueChangedListener() {
masterPasswordField.setOnFocusChangeListener( updateMasterKey ); @Override
siteNameField.addTextChangedListener( updateSitePassword ); void update() {
siteTypeField.setOnItemSelectedListener( updateSitePassword ); updateMasterKey();
counterField.addTextChangedListener( updateSitePassword ); }
siteVersionField.setOnItemSelectedListener( updateMasterKey ); } );
masterPasswordField.setOnFocusChangeListener( new ValueChangedListener() {
@Override
void update() {
updateMasterKey();
}
} );
siteNameField.addTextChangedListener( new ValueChangedListener() {
@Override
void update() {
siteCounterButton.setText( MessageFormat.format( "{0}", 1 ) );
updateSitePassword();
}
} );
siteTypeButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(final View v) {
@SuppressWarnings("SuspiciousMethodCalls")
MPSiteType siteType =
allSiteTypes.get( (allSiteTypes.indexOf( siteTypeButton.getTag() ) + 1) % allSiteTypes.size() );
preferences.setDefaultSiteType( siteType );
siteTypeButton.setTag( siteType );
siteTypeButton.setText( siteType.getShortName() );
updateSitePassword();
}
} );
siteCounterButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(final View v) {
UnsignedInteger counter =
UnsignedInteger.valueOf( siteCounterButton.getText().toString() ).plus( UnsignedInteger.ONE );
siteCounterButton.setText( MessageFormat.format( "{0}", counter ) );
updateSitePassword();
}
} );
siteVersionButton.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(final View v) {
@SuppressWarnings("SuspiciousMethodCalls")
MasterKey.Version siteVersion =
allVersions.get( (allVersions.indexOf( siteVersionButton.getTag() ) + 1) % allVersions.size() );
preferences.setDefaultVersion( siteVersion );
siteVersionButton.setTag( siteVersion );
siteVersionButton.setText( siteVersion.name() );
updateMasterKey();
}
} );
sitePasswordField.addTextChangedListener( new ValueChangedListener() { sitePasswordField.addTextChangedListener( new ValueChangedListener() {
@Override @Override
void update() { void update() {
@@ -127,32 +166,26 @@ public class EmergencyActivity extends Activity {
sitePasswordField.setTypeface( Res.sourceCodePro_Black ); sitePasswordField.setTypeface( Res.sourceCodePro_Black );
sitePasswordField.setPaintFlags( sitePasswordField.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG ); sitePasswordField.setPaintFlags( sitePasswordField.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG );
siteTypeField.setAdapter( new ArrayAdapter<>( this, R.layout.spinner_item, MPSiteType.forClass( MPSiteTypeClass.Generated ) ) );
siteTypeField.setSelection( MPSiteType.GeneratedLong.ordinal() );
siteVersionField.setAdapter( new ArrayAdapter<>( this, R.layout.spinner_item, MasterKey.Version.values() ) );
siteVersionField.setSelection( MasterKey.Version.CURRENT.ordinal() );
rememberFullNameField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { rememberFullNameField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) { public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
getPreferences( MODE_PRIVATE ).edit().putBoolean( "rememberFullName", isChecked ).apply(); preferences.setRememberFullName( isChecked );
if (isChecked) if (isChecked)
getPreferences( MODE_PRIVATE ).edit().putString( "fullName", fullNameField.getText().toString() ).apply(); preferences.setFullName( fullNameField.getText().toString() );
else else
getPreferences( MODE_PRIVATE ).edit().putString( "fullName", "" ).apply(); preferences.setFullName( null );
} }
} ); } );
forgetPasswordField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { forgetPasswordField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) { public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
getPreferences( MODE_PRIVATE ).edit().putBoolean( "forgetPassword", isChecked ).apply(); preferences.setForgetPassword( isChecked );
} }
} ); } );
maskPasswordField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { maskPasswordField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) { public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
getPreferences( MODE_PRIVATE ).edit().putBoolean( "maskPassword", isChecked ).apply(); preferences.setMaskPassword( isChecked );
sitePasswordField.setTransformationMethod( isChecked? new PasswordTransformationMethod(): null ); sitePasswordField.setTransformationMethod( isChecked? new PasswordTransformationMethod(): null );
} }
} ); } );
@@ -162,13 +195,24 @@ public class EmergencyActivity extends Activity {
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
fullNameField.setText( getPreferences( MODE_PRIVATE ).getString( "fullName", "" ) ); MasterKey.setAllowNativeByDefault( preferences.isAllowNativeKDF() );
rememberFullNameField.setChecked( isRememberFullNameEnabled() );
forgetPasswordField.setChecked( isForgetPasswordEnabled() );
maskPasswordField.setChecked( isMaskPasswordEnabled() );
sitePasswordField.setTransformationMethod( isMaskPasswordEnabled()? new PasswordTransformationMethod(): null );
if (TextUtils.isEmpty( masterPasswordField.getText() )) fullNameField.setText( preferences.getFullName() );
rememberFullNameField.setChecked( preferences.isRememberFullName() );
forgetPasswordField.setChecked( preferences.isForgetPassword() );
maskPasswordField.setChecked( preferences.isMaskPassword() );
sitePasswordField.setTransformationMethod( preferences.isMaskPassword()? new PasswordTransformationMethod(): null );
MPSiteType defaultSiteType = preferences.getDefaultSiteType();
siteTypeButton.setTag( defaultSiteType );
siteTypeButton.setText( defaultSiteType.getShortName() );
MasterKey.Version defaultVersion = preferences.getDefaultVersion();
siteVersionButton.setTag( defaultVersion );
siteVersionButton.setText( defaultVersion.name() );
siteCounterButton.setText( MessageFormat.format( "{0}", 1 ) );
if (TextUtils.isEmpty( fullNameField.getText() ))
fullNameField.requestFocus();
else if (TextUtils.isEmpty( masterPasswordField.getText() ))
masterPasswordField.requestFocus(); masterPasswordField.requestFocus();
else else
siteNameField.requestFocus(); siteNameField.requestFocus();
@@ -176,9 +220,9 @@ public class EmergencyActivity extends Activity {
@Override @Override
protected void onPause() { protected void onPause() {
if (isForgetPasswordEnabled()) { if (preferences.isForgetPassword()) {
synchronized (this) { synchronized (this) {
hc_userName = hc_masterPassword = 0; id_userName = id_masterPassword = 0;
if (masterKeyFuture != null) { if (masterKeyFuture != null) {
masterKeyFuture.cancel( true ); masterKeyFuture.cancel( true );
masterKeyFuture = null; masterKeyFuture = null;
@@ -195,35 +239,20 @@ public class EmergencyActivity extends Activity {
super.onPause(); super.onPause();
} }
private boolean isRememberFullNameEnabled() {
return getPreferences( MODE_PRIVATE ).getBoolean( "rememberFullName", false );
}
private boolean isForgetPasswordEnabled() {
return getPreferences( MODE_PRIVATE ).getBoolean( "forgetPassword", false );
}
private boolean isMaskPasswordEnabled() {
return getPreferences( MODE_PRIVATE ).getBoolean( "maskPassword", false );
}
private synchronized void updateMasterKey() { private synchronized void updateMasterKey() {
final String fullName = fullNameField.getText().toString(); final String fullName = fullNameField.getText().toString();
final char[] masterPassword = masterPasswordField.getText().toString().toCharArray(); final char[] masterPassword = masterPasswordField.getText().toString().toCharArray();
final MasterKey.Version version = (MasterKey.Version) siteVersionField.getSelectedItem(); final MasterKey.Version version = (MasterKey.Version) siteVersionButton.getTag();
try { if (fullName.hashCode() == id_userName && Arrays.hashCode( masterPassword ) == id_masterPassword &&
if (fullName.hashCode() == hc_userName && Arrays.hashCode( masterPassword ) == hc_masterPassword && version.ordinal() == id_version && masterKeyFuture != null && !masterKeyFuture.isCancelled())
masterKeyFuture != null && masterKeyFuture.get().getAlgorithmVersion() == version)
return; return;
}
catch (InterruptedException | ExecutionException e) {
return;
}
hc_userName = fullName.hashCode();
hc_masterPassword = Arrays.hashCode( masterPassword );
if (isRememberFullNameEnabled()) id_userName = fullName.hashCode();
getPreferences( MODE_PRIVATE ).edit().putString( "fullName", fullName ).apply(); id_masterPassword = Arrays.hashCode( masterPassword );
id_version = version.ordinal();
if (preferences.isRememberFullName())
preferences.setFullName( fullName );
if (masterKeyFuture != null) if (masterKeyFuture != null)
masterKeyFuture.cancel( true ); masterKeyFuture.cancel( true );
@@ -243,7 +272,7 @@ public class EmergencyActivity extends Activity {
try { try {
return MasterKey.create( version, fullName, masterPassword ); return MasterKey.create( version, fullName, masterPassword );
} }
catch (RuntimeException e) { catch (Exception e) {
sitePasswordField.setText( "" ); sitePasswordField.setText( "" );
progressView.setVisibility( View.INVISIBLE ); progressView.setVisibility( View.INVISIBLE );
logger.err( e, "While generating master key." ); logger.err( e, "While generating master key." );
@@ -265,8 +294,8 @@ public class EmergencyActivity extends Activity {
private void updateSitePassword() { private void updateSitePassword() {
final String siteName = siteNameField.getText().toString(); final String siteName = siteNameField.getText().toString();
final MPSiteType type = (MPSiteType) siteTypeField.getSelectedItem(); final MPSiteType type = (MPSiteType) siteTypeButton.getTag();
final UnsignedInteger counter = UnsignedInteger.valueOf( ifNotNullElse( counterField.getText(), "1" ).toString() ); final UnsignedInteger counter = UnsignedInteger.valueOf( siteCounterButton.getText().toString() );
if (masterKeyFuture == null || siteName.isEmpty() || type == null) { if (masterKeyFuture == null || siteName.isEmpty() || type == null) {
sitePasswordField.setText( "" ); sitePasswordField.setText( "" );
@@ -313,6 +342,14 @@ public class EmergencyActivity extends Activity {
} ); } );
} }
public void integrityTests(View view) {
if (masterKeyFuture != null) {
masterKeyFuture.cancel( true );
masterKeyFuture = null;
}
TestActivity.startNoSkip( this );
}
public void copySitePassword(View view) { public void copySitePassword(View view) {
final String currentSitePassword = this.sitePassword; final String currentSitePassword = this.sitePassword;
if (TextUtils.isEmpty( currentSitePassword )) if (TextUtils.isEmpty( currentSitePassword ))

View File

@@ -0,0 +1,148 @@
package com.lyndir.masterpassword;
import android.content.Context;
import android.content.SharedPreferences;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* @author lhunath, 2016-02-20
*/
public class Preferences {
private static final String PREF_TESTS_PASSED = "integrityTestsPassed";
private static final String PREF_NATIVE_KDF = "nativeKDF";
private static final String PREF_REMEMBER_FULL_NAME = "rememberFullName";
private static final String PREF_FORGET_PASSWORD = "forgetPassword";
private static final String PREF_MASK_PASSWORD = "maskPassword";
private static final String PREF_FULL_NAME = "fullName";
private static final String PREF_SITE_TYPE = "siteType";
private static final String PREF_ALGORITHM_VERSION = "algorithmVersion";
private static Preferences instance;
private Context context;
@Nullable
private SharedPreferences prefs;
public static synchronized Preferences get(final Context context) {
if (instance == null)
instance = new Preferences( context );
return instance;
}
private Preferences(Context context) {
this.context = context;
}
@Nonnull
private SharedPreferences prefs() {
if (prefs == null)
prefs = (context = context.getApplicationContext()).getSharedPreferences( getClass().getCanonicalName(), Context.MODE_PRIVATE );
return prefs;
}
public boolean setNativeKDFEnabled(boolean enabled) {
if (isAllowNativeKDF() == enabled)
return false;
prefs().edit().putBoolean( PREF_NATIVE_KDF, enabled ).apply();
return true;
}
public boolean isAllowNativeKDF() {
return prefs().getBoolean( PREF_NATIVE_KDF, MasterKey.isAllowNativeByDefault() );
}
public boolean setTestsPassed(final Set<String> value) {
if (Sets.symmetricDifference( getTestsPassed(), value ).isEmpty())
return false;
prefs().edit().putStringSet( PREF_TESTS_PASSED, value ).apply();
return true;
}
public Set<String> getTestsPassed() {
return prefs().getStringSet( PREF_TESTS_PASSED, ImmutableSet.<String>of() );
}
public boolean setRememberFullName(boolean enabled) {
if (isRememberFullName() == enabled)
return false;
prefs().edit().putBoolean( PREF_REMEMBER_FULL_NAME, enabled ).apply();
return true;
}
public boolean isRememberFullName() {
return prefs().getBoolean( PREF_REMEMBER_FULL_NAME, false );
}
public boolean setForgetPassword(boolean enabled) {
if (isForgetPassword() == enabled)
return false;
prefs().edit().putBoolean( PREF_FORGET_PASSWORD, enabled ).apply();
return true;
}
public boolean isForgetPassword() {
return prefs().getBoolean( PREF_FORGET_PASSWORD, false );
}
public boolean setMaskPassword(boolean enabled) {
if (isMaskPassword() == enabled)
return false;
prefs().edit().putBoolean( PREF_MASK_PASSWORD, enabled ).apply();
return true;
}
public boolean isMaskPassword() {
return prefs().getBoolean( PREF_MASK_PASSWORD, false );
}
public boolean setFullName(@Nullable String value) {
if (getFullName().equals( value ))
return false;
prefs().edit().putString( PREF_FULL_NAME, value ).apply();
return true;
}
@Nonnull
public String getFullName() {
return prefs().getString( PREF_FULL_NAME, "" );
}
public boolean setDefaultSiteType(@Nonnull MPSiteType value) {
if (getDefaultSiteType().equals( value ))
return false;
prefs().edit().putInt( PREF_SITE_TYPE, value.ordinal() ).apply();
return true;
}
@Nonnull
public MPSiteType getDefaultSiteType() {
return MPSiteType.values()[prefs().getInt( PREF_SITE_TYPE, MPSiteType.GeneratedLong.ordinal() )];
}
public boolean setDefaultVersion(@Nonnull MasterKey.Version value) {
if (getDefaultVersion().equals( value ))
return false;
prefs().edit().putInt( PREF_ALGORITHM_VERSION, value.ordinal() ).apply();
return true;
}
@Nonnull
public MasterKey.Version getDefaultVersion() {
return MasterKey.Version.values()[prefs().getInt( PREF_ALGORITHM_VERSION, MasterKey.Version.CURRENT.ordinal() )];
}
}

View File

@@ -3,9 +3,10 @@ package com.lyndir.masterpassword;
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf; import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
import android.app.*; import android.app.*;
import android.content.Context;
import android.content.Intent;
import android.os.*; import android.os.*;
import android.view.View; import android.view.View;
import android.view.WindowManager;
import android.widget.*; import android.widget.*;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.InjectView; import butterknife.InjectView;
@@ -13,7 +14,6 @@ import com.google.common.base.*;
import com.google.common.collect.*; import com.google.common.collect.*;
import com.google.common.util.concurrent.*; import com.google.common.util.concurrent.*;
import com.lyndir.lhunath.opal.system.logging.Logger; import com.lyndir.lhunath.opal.system.logging.Logger;
import java.util.Set;
import java.util.concurrent.*; import java.util.concurrent.*;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -23,6 +23,7 @@ public class TestActivity extends Activity implements MPTestSuite.Listener {
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
private static final Logger logger = Logger.get( TestActivity.class ); private static final Logger logger = Logger.get( TestActivity.class );
private final Preferences preferences = Preferences.get( this );
private final ListeningExecutorService backgroundExecutor = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor() ); private final ListeningExecutorService backgroundExecutor = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor() );
private final ListeningExecutorService mainExecutor = MoreExecutors.listeningDecorator( new MainThreadExecutor() ); private final ListeningExecutorService mainExecutor = MoreExecutors.listeningDecorator( new MainThreadExecutor() );
@@ -38,20 +39,34 @@ public class TestActivity extends Activity implements MPTestSuite.Listener {
@InjectView(R.id.actionButton) @InjectView(R.id.actionButton)
Button actionButton; Button actionButton;
@InjectView(R.id.nativeKDFField)
CheckBox nativeKDFField;
private MPTestSuite testSuite; private MPTestSuite testSuite;
private ListenableFuture<Boolean> testFuture; private ListenableFuture<Boolean> testFuture;
private Runnable action; private Runnable action;
private ImmutableSet<String> testNames; private ImmutableSet<String> testNames;
public static void startNoSkip(Context context) {
context.startActivity( new Intent( context, TestActivity.class ) );
}
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate( savedInstanceState ); super.onCreate( savedInstanceState );
Res.init( getResources() ); Res.init( getResources() );
getWindow().setFlags( WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE );
setContentView( R.layout.activity_test ); setContentView( R.layout.activity_test );
ButterKnife.inject( this ); ButterKnife.inject( this );
nativeKDFField.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
preferences.setNativeKDFEnabled( isChecked );
MasterKey.setAllowNativeByDefault( isChecked );
}
} );
try { try {
setStatus( 0, 0, null ); setStatus( 0, 0, null );
testSuite = new MPTestSuite(); testSuite = new MPTestSuite();
@@ -76,29 +91,22 @@ public class TestActivity extends Activity implements MPTestSuite.Listener {
} }
} }
@Override
protected void onStart() {
super.onStart();
final Set<String> integrityTestsPassed = getPreferences( MODE_PRIVATE ).getStringSet( "integrityTestsPassed",
ImmutableSet.<String>of() );
if (!FluentIterable.from( testNames ).anyMatch( new Predicate<String>() {
@Override
public boolean apply(@Nullable final String testName) {
return !integrityTestsPassed.contains( testName );
}
} )) {
// None of the tests we need to perform were missing from the tests that have already been passed on this device.
finish();
EmergencyActivity.start( TestActivity.this );
}
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
if (testFuture == null) { nativeKDFField.setChecked( preferences.isAllowNativeKDF() );
if (testFuture == null)
startTestSuite();
}
private void startTestSuite() {
if (testFuture != null)
testFuture.cancel( true );
MasterKey.setAllowNativeByDefault( preferences.isAllowNativeKDF() );
setStatus( R.string.tests_testing, R.string.tests_btn_testing, null ); setStatus( R.string.tests_testing, R.string.tests_btn_testing, null );
Futures.addCallback( testFuture = backgroundExecutor.submit( testSuite ), new FutureCallback<Boolean>() { Futures.addCallback( testFuture = backgroundExecutor.submit( testSuite ), new FutureCallback<Boolean>() {
@Override @Override
@@ -107,16 +115,15 @@ public class TestActivity extends Activity implements MPTestSuite.Listener {
setStatus( R.string.tests_passed, R.string.tests_btn_passed, new Runnable() { setStatus( R.string.tests_passed, R.string.tests_btn_passed, new Runnable() {
@Override @Override
public void run() { public void run() {
getPreferences( MODE_PRIVATE ).edit().putStringSet( "integrityTestsPassed", testNames ).apply(); preferences.setTestsPassed( testNames );
finish(); finish();
EmergencyActivity.start( TestActivity.this );
} }
} ); } );
else else
setStatus( R.string.tests_failed, R.string.tests_btn_failed, new Runnable() { setStatus( R.string.tests_failed, R.string.tests_btn_failed, new Runnable() {
@Override @Override
public void run() { public void run() {
finish(); startTestSuite();
} }
} ); } );
} }
@@ -133,7 +140,6 @@ public class TestActivity extends Activity implements MPTestSuite.Listener {
} }
}, mainExecutor ); }, mainExecutor );
} }
}
public void onAction(View v) { public void onAction(View v) {
if (action != null) if (action != null)

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword</artifactId> <artifactId>masterpassword</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</parent> </parent>
<name>Master Password CLI</name> <name>Master Password CLI</name>
@@ -85,7 +85,7 @@
<dependency> <dependency>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword-algorithm</artifactId> <artifactId>masterpassword-algorithm</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -1,15 +1,15 @@
<configuration scan="false"> <configuration scan="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout"> <encoder>
<Pattern>%-8relative %22c{0} [%-5level] %msg%n</Pattern> <pattern>%-8relative %22c{0} [%-5level] %msg%n</pattern>
</layout> </encoder>
</appender> </appender>
<logger name="com.lyndir" level="${mp.log.level:-INFO}" /> <logger name="com.lyndir" level="${mp.log.level:-INFO}" />
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="stdout" />
</root> </root>
</configuration> </configuration>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword</artifactId> <artifactId>masterpassword</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</parent> </parent>
<name>Master Password GUI</name> <name>Master Password GUI</name>
@@ -97,6 +97,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId> <artifactId>maven-jarsigner-plugin</artifactId>
<version>1.4</version>
<executions> <executions>
<execution> <execution>
<id>signing</id> <id>signing</id>
@@ -134,7 +135,7 @@
<dependency> <dependency>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword-model</artifactId> <artifactId>masterpassword-model</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</dependency> </dependency>
<!-- EXTERNAL DEPENDENCIES --> <!-- EXTERNAL DEPENDENCIES -->

View File

@@ -1,15 +1,15 @@
<configuration scan="false"> <configuration scan="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout"> <encoder>
<Pattern>%-8relative %22c{0} [%-5level] %msg%n</Pattern> <pattern>%-8relative %22c{0} [%-5level] %msg%n</pattern>
</layout> </encoder>
</appender> </appender>
<logger name="com.lyndir" level="${mp.log.level:-INFO}" /> <logger name="com.lyndir" level="${mp.log.level:-INFO}" />
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="stdout" />
</root> </root>
</configuration> </configuration>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword</artifactId> <artifactId>masterpassword</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</parent> </parent>
<name>Master Password Site Model</name> <name>Master Password Site Model</name>
@@ -23,7 +23,7 @@
<dependency> <dependency>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword-algorithm</artifactId> <artifactId>masterpassword-algorithm</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</dependency> </dependency>
<!-- EXTERNAL DEPENDENCIES --> <!-- EXTERNAL DEPENDENCIES -->

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword</artifactId> <artifactId>masterpassword</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</parent> </parent>
<name>Master Password Test Suite</name> <name>Master Password Test Suite</name>
@@ -23,7 +23,7 @@
<dependency> <dependency>
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword-algorithm</artifactId> <artifactId>masterpassword-algorithm</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
</dependency> </dependency>
<!-- TESTING --> <!-- TESTING -->

View File

@@ -1,15 +1,15 @@
<configuration scan="false"> <configuration scan="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout"> <encoder>
<Pattern>%-8relative %22c{0} [%-5level] %msg%n</Pattern> <pattern>%-8relative %22c{0} [%-5level] %msg%n</pattern>
</layout> </encoder>
</appender> </appender>
<logger name="com.lyndir.masterpassword" level="${mp.log.level:-TRACE}" /> <logger name="com.lyndir" level="${mp.log.level:-INFO}" />
<root level="INFO"> <root level="INFO">
<appender-ref ref="STDOUT" /> <appender-ref ref="stdout" />
</root> </root>
</configuration> </configuration>

View File

@@ -15,7 +15,7 @@
<groupId>com.lyndir.masterpassword</groupId> <groupId>com.lyndir.masterpassword</groupId>
<artifactId>masterpassword</artifactId> <artifactId>masterpassword</artifactId>
<version>2.3.1</version> <version>2.4-java</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<modules> <modules>
@@ -60,6 +60,6 @@
</repositories> </repositories>
<scm> <scm>
<tag>2.3.1</tag> <tag>2.4-java</tag>
</scm> </scm>
</project> </project>

View File

@@ -36,7 +36,7 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
- (void)reloadProducts { - (void)reloadProducts {
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers: SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:
[[NSSet alloc] initWithObjects:MPProductGenerateLogins, MPProductGenerateAnswers, MPProductFuel, nil]]; [[NSSet alloc] initWithObjects:MPProductGenerateLogins, MPProductGenerateAnswers, MPProductTouchID, MPProductFuel, nil]];
productsRequest.delegate = self; productsRequest.delegate = self;
[productsRequest start]; [productsRequest start];
} }

View File

@@ -8,6 +8,7 @@
#import "MPAppDelegate_Key.h" #import "MPAppDelegate_Key.h"
#import "MPAppDelegate_Store.h" #import "MPAppDelegate_Store.h"
#import <LocalAuthentication/LocalAuthentication.h>
@interface MPAppDelegate_Shared() @interface MPAppDelegate_Shared()
@@ -17,50 +18,76 @@
@implementation MPAppDelegate_Shared(Key) @implementation MPAppDelegate_Shared(Key)
static NSDictionary *keyQuery(MPUserEntity *user) { static NSDictionary *createKeyQuery(MPUserEntity *user, BOOL newItem, MPKeyOrigin *keyOrigin) {
#if TARGET_OS_IPHONE
if (user.touchID && kSecUseOperationPrompt) {
if (keyOrigin)
*keyOrigin = MPKeyOriginKeyChainBiometric;
CFErrorRef acError = NULL;
SecAccessControlRef accessControl = SecAccessControlCreateWithFlags( kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, kSecAccessControlTouchIDCurrentSet, &acError );
if (!accessControl || acError)
err( @"Could not use TouchID on this device: %@", acError );
else
return [PearlKeyChain createQueryForClass:kSecClassGenericPassword
attributes:@{
(__bridge id)kSecAttrService : @"Saved Master Password",
(__bridge id)kSecAttrAccount : user.name?: @"",
(__bridge id)kSecAttrAccessControl : (__bridge id)accessControl,
(__bridge id)kSecUseAuthenticationUI : (__bridge id)kSecUseAuthenticationUIAllow,
(__bridge id)kSecUseOperationPrompt :
strf( @"Access %@'s master password.", user.name ),
}
matches:nil];
}
#endif
if (keyOrigin)
*keyOrigin = MPKeyOriginKeyChain;
return [PearlKeyChain createQueryForClass:kSecClassGenericPassword return [PearlKeyChain createQueryForClass:kSecClassGenericPassword
attributes:@{ attributes:@{
(__bridge id)kSecAttrService : @"Saved Master Password", (__bridge id)kSecAttrService : @"Saved Master Password",
(__bridge id)kSecAttrAccount : user.name?: @"" (__bridge id)kSecAttrAccount : user.name?: @"",
#if TARGET_OS_IPHONE
(__bridge id)kSecAttrAccessible : (__bridge id)(kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly?: kSecAttrAccessibleWhenUnlockedThisDeviceOnly),
#endif
} }
matches:nil]; matches:nil];
} }
- (MPKey *)loadSavedKeyFor:(MPUserEntity *)user { - (MPKey *)loadSavedKeyFor:(MPUserEntity *)user {
NSData *keyData = [PearlKeyChain dataOfItemForQuery:keyQuery( user )]; MPKeyOrigin keyOrigin;
NSDictionary *keyQuery = createKeyQuery( user, NO, &keyOrigin );
NSData *keyData = [PearlKeyChain dataOfItemForQuery:keyQuery];
if (!keyData) { if (!keyData) {
inf( @"No key found in keychain for user: %@", user.userID ); inf( @"No key found in keychain for user: %@", user.userID );
return nil; return nil;
} }
inf( @"Found key in keychain for user: %@", user.userID ); inf( @"Found key in keychain for user: %@", user.userID );
return [[MPKey alloc] initForFullName:user.name withKeyData:keyData forAlgorithm:user.algorithm]; return [[MPKey alloc] initForFullName:user.name withKeyData:keyData forAlgorithm:user.algorithm keyOrigin:keyOrigin];
} }
- (void)storeSavedKeyFor:(MPUserEntity *)user { - (void)storeSavedKeyFor:(MPUserEntity *)user {
if (user.saveKey) { if (user.saveKey) {
NSData *existingKeyData = [PearlKeyChain dataOfItemForQuery:keyQuery( user )];
if (![existingKeyData isEqualToData:[self.key keyDataForAlgorithm:user.algorithm]]) {
inf( @"Saving key in keychain for user: %@", user.userID ); inf( @"Saving key in keychain for user: %@", user.userID );
[PearlKeyChain addOrUpdateItemForQuery:keyQuery( user ) [PearlKeyChain addOrUpdateItemForQuery:createKeyQuery( user, YES, nil )
withAttributes:@{ withAttributes:@{
(__bridge id)kSecValueData : [self.key keyDataForAlgorithm:user.algorithm], (__bridge id)kSecValueData : [self.key keyDataForAlgorithm:user.algorithm],
#if TARGET_OS_IPHONE
(__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
#endif
}]; }];
} }
}
} }
- (void)forgetSavedKeyFor:(MPUserEntity *)user { - (void)forgetSavedKeyFor:(MPUserEntity *)user {
OSStatus result = [PearlKeyChain deleteItemForQuery:keyQuery( user )]; OSStatus result = [PearlKeyChain deleteItemForQuery:createKeyQuery( user, NO, nil )];
if (result == noErr) { if (result == noErr) {
inf( @"Removed key from keychain for user: %@", user.userID ); inf( @"Removed key from keychain for user: %@", user.userID );
@@ -79,8 +106,7 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
- (BOOL)signInAsUser:(MPUserEntity *)user saveInContext:(NSManagedObjectContext *)moc usingMasterPassword:(NSString *)password { - (BOOL)signInAsUser:(MPUserEntity *)user saveInContext:(NSManagedObjectContext *)moc usingMasterPassword:(NSString *)password {
if (password) NSAssert( ![NSThread isMainThread], @"Authentication should not happen on the main thread." );
NSAssert( ![NSThread isMainThread], @"Computing key must not happen from the main thread." );
if (!user) if (!user)
return NO; return NO;
@@ -144,7 +170,17 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
} }
self.key = tryKey; self.key = tryKey;
// Update the key chain if necessary.
switch (self.key.origin) {
case MPKeyOriginMasterPassword:
[self storeSavedKeyFor:user]; [self storeSavedKeyFor:user];
break;
case MPKeyOriginKeyChain:
case MPKeyOriginKeyChainBiometric:
break;
}
} }
@try { @try {

View File

@@ -22,6 +22,13 @@
@end @end
@interface MPSiteQuestionEntity(MP)
- (NSString *)resolveQuestionAnswerUsingKey:(MPKey *)key;
- (void)resolveQuestionAnswerUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result;
@end
@interface MPSiteEntity(MP)<MPFixable> @interface MPSiteEntity(MP)<MPFixable>
@property(assign) BOOL loginGenerated; @property(assign) BOOL loginGenerated;
@@ -38,8 +45,10 @@
- (BOOL)tryMigrateExplicitly:(BOOL)explicit; - (BOOL)tryMigrateExplicitly:(BOOL)explicit;
- (NSString *)resolveLoginUsingKey:(MPKey *)key; - (NSString *)resolveLoginUsingKey:(MPKey *)key;
- (NSString *)resolvePasswordUsingKey:(MPKey *)key; - (NSString *)resolvePasswordUsingKey:(MPKey *)key;
- (NSString *)resolveSiteAnswerUsingKey:(MPKey *)key;
- (void)resolveLoginUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result; - (void)resolveLoginUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result;
- (void)resolvePasswordUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result; - (void)resolvePasswordUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result;
- (void)resolveSiteAnswerUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result;
@end @end
@@ -53,6 +62,7 @@
@property(assign) NSUInteger avatar; @property(assign) NSUInteger avatar;
@property(assign) BOOL saveKey; @property(assign) BOOL saveKey;
@property(assign) BOOL touchID;
@property(assign) MPSiteType defaultType; @property(assign) MPSiteType defaultType;
@property(readonly) NSString *userID; @property(readonly) NSString *userID;
@property(strong) id<MPAlgorithm> algorithm; @property(strong) id<MPAlgorithm> algorithm;

View File

@@ -9,6 +9,7 @@
#import "MPEntities.h" #import "MPEntities.h"
#import "MPAppDelegate_Shared.h" #import "MPAppDelegate_Shared.h"
#import "MPAppDelegate_Key.h" #import "MPAppDelegate_Key.h"
#import "MPAppDelegate_InApp.h"
@implementation NSManagedObjectContext(MP) @implementation NSManagedObjectContext(MP)
@@ -34,6 +35,20 @@
@end @end
@implementation MPSiteQuestionEntity(MP)
- (NSString *)resolveQuestionAnswerUsingKey:(MPKey *)key {
return [self.site.algorithm resolveAnswerForQuestion:self usingKey:key];
}
- (void)resolveQuestionAnswerUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result {
[self.site.algorithm resolveAnswerForQuestion:self usingKey:key result:result];
}
@end
@implementation MPSiteEntity(MP) @implementation MPSiteEntity(MP)
- (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context { - (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context {
@@ -174,6 +189,11 @@
return [self.algorithm resolvePasswordForSite:self usingKey:key]; return [self.algorithm resolvePasswordForSite:self usingKey:key];
} }
- (NSString *)resolveSiteAnswerUsingKey:(MPKey *)key {
return [self.algorithm resolveAnswerForSite:self usingKey:key];
}
- (void)resolveLoginUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result { - (void)resolveLoginUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result {
[self.algorithm resolveLoginForSite:self usingKey:key result:result]; [self.algorithm resolveLoginForSite:self usingKey:key result:result];
@@ -184,6 +204,11 @@
[self.algorithm resolvePasswordForSite:self usingKey:key result:result]; [self.algorithm resolvePasswordForSite:self usingKey:key result:result];
} }
- (void)resolveSiteAnswerUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result {
[self.algorithm resolveAnswerForSite:self usingKey:key result:result];
}
@end @end
@implementation MPGeneratedSiteEntity(MP) @implementation MPGeneratedSiteEntity(MP)
@@ -285,6 +310,16 @@
self.saveKey_ = @(aSaveKey); self.saveKey_ = @(aSaveKey);
} }
- (BOOL)touchID {
return [self.touchID_ boolValue] && [[MPAppDelegate_Shared get] isFeatureUnlocked:MPProductTouchID];
}
- (void)setTouchID:(BOOL)aTouchID {
self.touchID_ = @(aTouchID);
}
- (MPSiteType)defaultType { - (MPSiteType)defaultType {
return (MPSiteType)[self.defaultType_ unsignedIntegerValue]?: MPSiteTypeGeneratedLong; return (MPSiteType)[self.defaultType_ unsignedIntegerValue]?: MPSiteTypeGeneratedLong;

View File

@@ -20,12 +20,20 @@
@protocol MPAlgorithm; @protocol MPAlgorithm;
typedef NS_ENUM(NSUInteger, MPKeyOrigin) {
MPKeyOriginMasterPassword,
MPKeyOriginKeyChain,
MPKeyOriginKeyChainBiometric,
};
@interface MPKey : NSObject @interface MPKey : NSObject
@property(nonatomic, readonly) NSString *fullName; @property(nonatomic, readonly) NSString *fullName;
@property(nonatomic, readonly) MPKeyOrigin origin;
- (instancetype)initForFullName:(NSString *)fullName withMasterPassword:(NSString *)masterPassword; - (instancetype)initForFullName:(NSString *)fullName withMasterPassword:(NSString *)masterPassword;
- (instancetype)initForFullName:(NSString *)fullName withKeyData:(NSData *)keyData forAlgorithm:(id<MPAlgorithm>)algorithm; - (instancetype)initForFullName:(NSString *)fullName withKeyData:(NSData *)keyData
forAlgorithm:(id<MPAlgorithm>)algorithm keyOrigin:(MPKeyOrigin)origin;
- (NSData *)keyIDForAlgorithm:(id<MPAlgorithm>)algorithm; - (NSData *)keyIDForAlgorithm:(id<MPAlgorithm>)algorithm;
- (NSData *)keyDataForAlgorithm:(id<MPAlgorithm>)algorithm; - (NSData *)keyDataForAlgorithm:(id<MPAlgorithm>)algorithm;

View File

@@ -20,6 +20,7 @@
@interface MPKey() @interface MPKey()
@property(nonatomic) NSString *fullName; @property(nonatomic) NSString *fullName;
@property(nonatomic) MPKeyOrigin origin;
@property(nonatomic) NSString *masterPassword; @property(nonatomic) NSString *masterPassword;
@end @end
@@ -35,16 +36,19 @@
_keyCache = [NSCache new]; _keyCache = [NSCache new];
self.fullName = fullName; self.fullName = fullName;
self.origin = MPKeyOriginMasterPassword;
self.masterPassword = masterPassword; self.masterPassword = masterPassword;
return self; return self;
} }
- (instancetype)initForFullName:(NSString *)fullName withKeyData:(NSData *)keyData forAlgorithm:(id<MPAlgorithm>)algorithm { - (instancetype)initForFullName:(NSString *)fullName withKeyData:(NSData *)keyData
forAlgorithm:(id<MPAlgorithm>)algorithm keyOrigin:(MPKeyOrigin)origin {
if (!(self = [self initForFullName:fullName withMasterPassword:nil])) if (!(self = [self initForFullName:fullName withMasterPassword:nil]))
return nil; return nil;
self.origin = origin;
[_keyCache setObject:keyData forKey:algorithm]; [_keyCache setObject:keyData forKey:algorithm];
return self; return self;

View File

@@ -19,6 +19,7 @@
@property (nonatomic, retain) NSDate * lastUsed; @property (nonatomic, retain) NSDate * lastUsed;
@property (nonatomic, retain) NSString * name; @property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * saveKey_; @property (nonatomic, retain) NSNumber * saveKey_;
@property (nonatomic, retain) NSNumber * touchID_;
@property (nonatomic, retain) NSNumber * version_; @property (nonatomic, retain) NSNumber * version_;
@property (nonatomic, retain) NSSet *sites; @property (nonatomic, retain) NSSet *sites;
@end @end

View File

@@ -18,6 +18,7 @@
@dynamic lastUsed; @dynamic lastUsed;
@dynamic name; @dynamic name;
@dynamic saveKey_; @dynamic saveKey_;
@dynamic touchID_;
@dynamic version_; @dynamic version_;
@dynamic sites; @dynamic sites;

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/> <capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
</dependencies> </dependencies>
<objects> <objects>

View File

@@ -16,7 +16,7 @@
return self; return self;
[self.defaults registerDefaults:@{ [self.defaults registerDefaults:@{
NSStringFromSelector( @selector(iTunesID) ) : @"510296984", NSStringFromSelector( @selector(appleID) ) : @"510296984",
}]; }];
return self; return self;

View File

@@ -28,6 +28,7 @@
@property(nonatomic) NSString *masterPassword; @property(nonatomic) NSString *masterPassword;
@property(nonatomic) BOOL showVersionContainer; @property(nonatomic) BOOL showVersionContainer;
@property(nonatomic) BOOL alternatePressed; @property(nonatomic) BOOL alternatePressed;
@property(nonatomic) BOOL shiftPressed;
@property(nonatomic) BOOL locked; @property(nonatomic) BOOL locked;
@property(nonatomic) BOOL newUser; @property(nonatomic) BOOL newUser;

View File

@@ -124,6 +124,10 @@
- (void)flagsChanged:(NSEvent *)theEvent { - (void)flagsChanged:(NSEvent *)theEvent {
BOOL shiftPressed = (theEvent.modifierFlags & NSShiftKeyMask) != 0;
if (shiftPressed != self.shiftPressed)
self.shiftPressed = shiftPressed;
BOOL alternatePressed = (theEvent.modifierFlags & NSAlternateKeyMask) != 0; BOOL alternatePressed = (theEvent.modifierFlags & NSAlternateKeyMask) != 0;
if (alternatePressed != self.alternatePressed) { if (alternatePressed != self.alternatePressed) {
self.alternatePressed = alternatePressed; self.alternatePressed = alternatePressed;
@@ -486,7 +490,7 @@
} }
// Performing action while content is available. Copy it. // Performing action while content is available. Copy it.
[self copyContent:selectedSite.content]; [self copyContent:self.shiftPressed? selectedSite.answer: selectedSite.content];
[self fadeOut]; [self fadeOut];

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9059" systemVersion="15B42" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9059"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
<capability name="box content view" minToolsVersion="7.0"/> <capability name="box content view" minToolsVersion="7.0"/>
<capability name="stacking Non-gravity area distributions on NSStackView" minToolsVersion="7.0" minSystemVersion="10.11"/> <capability name="stacking Non-gravity area distributions on NSStackView" minToolsVersion="7.0" minSystemVersion="10.11"/>
</dependencies> </dependencies>
@@ -28,10 +28,10 @@
<window title="Master Password" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hasShadow="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MPPasswordWindow"> <window title="Master Password" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hasShadow="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MPPasswordWindow">
<windowCollectionBehavior key="collectionBehavior" moveToActiveSpace="YES" transient="YES" ignoresCycle="YES" fullScreenAuxiliary="YES"/> <windowCollectionBehavior key="collectionBehavior" moveToActiveSpace="YES" transient="YES" ignoresCycle="YES" fullScreenAuxiliary="YES"/>
<rect key="contentRect" x="0.0" y="0.0" width="640" height="560"/> <rect key="contentRect" x="0.0" y="0.0" width="640" height="560"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/> <rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ" userLabel="Root"> <view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ" userLabel="Root">
<rect key="frame" x="0.0" y="0.0" width="640" height="560"/> <rect key="frame" x="0.0" y="0.0" width="640" height="560"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Bwc-sd-6gm" userLabel="Screen Capture"> <imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Bwc-sd-6gm" userLabel="Screen Capture">
<rect key="frame" x="-80" y="-80" width="800" height="720"/> <rect key="frame" x="-80" y="-80" width="800" height="720"/>
@@ -55,19 +55,16 @@
</configuration> </configuration>
</ciFilter> </ciFilter>
</contentFilters> </contentFilters>
<animations/>
<imageCell key="cell" enabled="NO" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="small-screen" id="ArA-2w-I56"/> <imageCell key="cell" enabled="NO" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="small-screen" id="ArA-2w-I56"/>
</imageView> </imageView>
<progressIndicator hidden="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="oSh-Ec-8Nf" userLabel="Progress Spinner"> <progressIndicator hidden="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="oSh-Ec-8Nf" userLabel="Progress Spinner">
<rect key="frame" x="312" y="524" width="16" height="16"/> <rect key="frame" x="312" y="524" width="16" height="16"/>
<animations/>
</progressIndicator> </progressIndicator>
<button translatesAutoresizingMaskIntoConstraints="NO" id="Aue-Zx-6Mf" userLabel="Settings Gear"> <button translatesAutoresizingMaskIntoConstraints="NO" id="Aue-Zx-6Mf" userLabel="Settings Gear">
<rect key="frame" x="588" y="508" width="32" height="32"/> <rect key="frame" x="585" y="496" width="35" height="44"/>
<animations/> <buttonCell key="cell" type="square" title="⚙" bezelStyle="shadowlessSquare" alignment="center" imageScaling="proportionallyDown" inset="2" id="i8r-9N-vcQ">
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="icon_gear" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="i8r-9N-vcQ">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" size="48" name="AppleSymbols"/>
<string key="keyEquivalent">,</string> <string key="keyEquivalent">,</string>
<modifierMask key="keyEquivalentModifierMask" command="YES"/> <modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell> </buttonCell>
@@ -76,12 +73,11 @@
</connections> </connections>
</button> </button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gAU-xs-aae"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gAU-xs-aae">
<rect key="frame" x="595" y="490" width="19" height="14"/> <rect key="frame" x="593" y="478" width="19" height="14"/>
<shadow key="shadow" blurRadius="0.5"> <shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘," id="Xm1-qb-6EP"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘," id="Xm1-qb-6EP">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -101,7 +97,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" focusRingType="none" alignment="center" usesSingleLineMode="YES" id="NcX-1Z-2OC"> <secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" focusRingType="none" alignment="center" usesSingleLineMode="YES" id="NcX-1Z-2OC">
<font key="font" metaFont="system" size="36"/> <font key="font" metaFont="system" size="36"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -137,7 +132,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" focusRingType="none" alignment="center" placeholderString="" usesSingleLineMode="YES" id="gRw-5C-YUN"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" focusRingType="none" alignment="center" placeholderString="" usesSingleLineMode="YES" id="gRw-5C-YUN">
<font key="font" metaFont="system" size="36"/> <font key="font" metaFont="system" size="36"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -173,7 +167,6 @@
</textField> </textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R46-fx-n14"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R46-fx-n14">
<rect key="frame" x="232" y="19" width="177" height="19"/> <rect key="frame" x="232" y="19" width="177" height="19"/>
<animations/>
<buttonCell key="cell" type="recessed" title="Reset My Master Password" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="B7Z-72-fVP" customClass="MPNoStateButtonCell"> <buttonCell key="cell" type="recessed" title="Reset My Master Password" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="B7Z-72-fVP" customClass="MPNoStateButtonCell">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/> <font key="font" metaFont="systemBold" size="12"/>
@@ -193,7 +186,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.70000000000000007" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="0.70000000000000007" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Hold alt ⌥ to temporarily reveal what you've typed." id="4Ep-xX-Ky8"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Hold alt ⌥ to temporarily reveal what you've typed." id="4Ep-xX-Ky8">
<font key="font" size="11" name="HelveticaNeue"/> <font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -225,7 +217,6 @@
</configuration> </configuration>
</ciFilter> </ciFilter>
</contentFilters> </contentFilters>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="KeljXoleKowi9@" placeholderString="" id="WVV-EE-tkB"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="KeljXoleKowi9@" placeholderString="" id="WVV-EE-tkB">
<font key="font" size="64" name="SourceCodePro-Regular"/> <font key="font" size="64" name="SourceCodePro-Regular"/>
<color key="textColor" name="keyboardFocusIndicatorColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="keyboardFocusIndicatorColor" catalog="System" colorSpace="catalog"/>
@@ -240,19 +231,77 @@
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.displayedContent" id="Sdg-fb-kQK"/> <binding destination="mcS-ik-b0n" name="value" keyPath="selection.displayedContent" id="Sdg-fb-kQK"/>
</connections> </connections>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ond-dT-x5d" userLabel="Site Password Tip"> <searchField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eBx-2g-chS" userLabel="Site Question">
<rect key="frame" x="220" y="146" width="160" height="14"/> <rect key="frame" x="42" y="33" width="516" height="14"/>
<constraints>
<constraint firstAttribute="width" constant="512" id="JSe-85-4H0"/>
</constraints>
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" red="0.0" green="0.0" blue="0.0" alpha="0.80000000000000004" colorSpace="calibratedRGB"/>
</shadow>
<searchFieldCell key="cell" controlSize="small" selectable="YES" editable="YES" focusRingType="none" alignment="center" placeholderString="Question Keyword" sendsSearchStringImmediately="YES" id="sZN-Vi-v8k">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
<connections>
<action selector="doSearchSites:" target="-2" id="72O-59-xYV"/>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="Skr-1g-quT">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.question" id="3AM-pr-HBA"/>
<outlet property="delegate" destination="-2" id="c5n-ve-3Uw"/>
</connections>
</searchField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cp4-2G-8aG" userLabel="Site Answer">
<rect key="frame" x="189" y="12" width="221" height="29"/>
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<contentFilters>
<ciFilter name="CIGloom">
<configuration>
<null key="inputImage"/>
<real key="inputIntensity" value="0.80000000000000004"/>
<real key="inputRadius" value="8"/>
</configuration>
</ciFilter>
</contentFilters>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="fewc fom pugsuhe xav" placeholderString="" id="oYj-IR-xmw">
<font key="font" size="18" name="SourceCodePro-Regular"/>
<color key="textColor" name="keyboardFocusIndicatorColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="TxZ-TU-RMn">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.answer" id="Ba7-t3-euS"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ond-dT-x5d" userLabel="Site Password Tip">
<rect key="frame" x="220" y="138" width="160" height="14"/>
<shadow key="shadow" blurRadius="0.5"> <shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Your password for apple.com:" id="CgJ-XZ-6Hy"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Your password for apple.com:" id="CgJ-XZ-6Hy">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
<connections> <connections>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="Jvv-jZ-PG1">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="hidden2" keyPath="selection.content.length" previousBinding="Jvv-jZ-PG1" id="OXN-Zm-1ra"> <binding destination="mcS-ik-b0n" name="hidden2" keyPath="selection.content.length" previousBinding="Jvv-jZ-PG1" id="OXN-Zm-1ra">
<dictionary key="options"> <dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/> <integer key="NSMultipleValuesPlaceholder" value="-1"/>
@@ -262,11 +311,6 @@
<string key="NSValueTransformerName">NSNegateBoolean</string> <string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary> </dictionary>
</binding> </binding>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="Jvv-jZ-PG1">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections> </connections>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ia6-7b-dFr"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ia6-7b-dFr">
@@ -275,7 +319,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="No password set. Click &quot;Change Password&quot; on the bottom to set one." id="eDQ-iz-97a"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="No password set. Click &quot;Change Password&quot; on the bottom to set one." id="eDQ-iz-97a">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -312,7 +355,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Master Password generates passwords for your sites (and other things)." id="YyD-hd-wi3"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Master Password generates passwords for your sites (and other things)." id="YyD-hd-wi3">
<font key="font" size="16" name="HelveticaNeue"/> <font key="font" size="16" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -341,7 +383,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" id="9c4-NI-NM0"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" id="9c4-NI-NM0">
<font key="font" size="12" name="HelveticaNeue"/> <font key="font" size="12" name="HelveticaNeue"/>
<string key="title">— When you create a new account, use the password Master Password gives you for it. <string key="title">— When you create a new account, use the password Master Password gives you for it.
@@ -373,16 +414,19 @@
<constraints> <constraints>
<constraint firstAttribute="centerY" secondItem="XUV-zU-Y9c" secondAttribute="centerY" id="6Qf-5O-Cvk"/> <constraint firstAttribute="centerY" secondItem="XUV-zU-Y9c" secondAttribute="centerY" id="6Qf-5O-Cvk"/>
<constraint firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="7sl-qi-HY9"/> <constraint firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="7sl-qi-HY9"/>
<constraint firstItem="cp4-2G-8aG" firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="Dx0-IB-hUM"/>
<constraint firstItem="Ia6-7b-dFr" firstAttribute="centerY" secondItem="XUV-zU-Y9c" secondAttribute="centerY" id="KqM-uR-Obm"/> <constraint firstItem="Ia6-7b-dFr" firstAttribute="centerY" secondItem="XUV-zU-Y9c" secondAttribute="centerY" id="KqM-uR-Obm"/>
<constraint firstItem="Ia6-7b-dFr" firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="NFQ-aw-8tm"/> <constraint firstItem="Ia6-7b-dFr" firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="NFQ-aw-8tm"/>
<constraint firstAttribute="centerX" secondItem="sYt-eL-uwt" secondAttribute="centerX" id="OFw-vb-I71"/> <constraint firstAttribute="centerX" secondItem="sYt-eL-uwt" secondAttribute="centerX" id="OFw-vb-I71"/>
<constraint firstItem="XUV-zU-Y9c" firstAttribute="top" secondItem="Ond-dT-x5d" secondAttribute="bottom" constant="8" symbolic="YES" id="UgV-J6-B5T"/> <constraint firstItem="cp4-2G-8aG" firstAttribute="top" secondItem="XUV-zU-Y9c" secondAttribute="bottom" id="T6W-P9-0vj"/>
<constraint firstItem="XUV-zU-Y9c" firstAttribute="top" secondItem="Ond-dT-x5d" secondAttribute="bottom" id="UgV-J6-B5T"/>
<constraint firstItem="Ond-dT-x5d" firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="UhT-LQ-aZ8"/> <constraint firstItem="Ond-dT-x5d" firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="UhT-LQ-aZ8"/>
<constraint firstItem="eBx-2g-chS" firstAttribute="centerX" secondItem="cp4-2G-8aG" secondAttribute="centerX" id="cHz-Q1-8ii"/>
<constraint firstItem="sYt-eL-uwt" firstAttribute="top" secondItem="OaQ-of-zmb" secondAttribute="bottom" constant="8" symbolic="YES" id="hjJ-f1-mFv"/> <constraint firstItem="sYt-eL-uwt" firstAttribute="top" secondItem="OaQ-of-zmb" secondAttribute="bottom" constant="8" symbolic="YES" id="hjJ-f1-mFv"/>
<constraint firstItem="cp4-2G-8aG" firstAttribute="top" secondItem="eBx-2g-chS" secondAttribute="bottom" constant="-8" id="inf-AC-ger"/>
<constraint firstItem="sYt-eL-uwt" firstAttribute="centerX" secondItem="OaQ-of-zmb" secondAttribute="centerX" id="mu2-se-Mtn"/> <constraint firstItem="sYt-eL-uwt" firstAttribute="centerX" secondItem="OaQ-of-zmb" secondAttribute="centerX" id="mu2-se-Mtn"/>
<constraint firstAttribute="centerY" secondItem="sYt-eL-uwt" secondAttribute="centerY" id="zLS-QG-MKS"/> <constraint firstAttribute="centerY" secondItem="sYt-eL-uwt" secondAttribute="centerY" id="zLS-QG-MKS"/>
</constraints> </constraints>
<animations/>
</customView> </customView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OnR-s6-d4P" userLabel="Site Name Label"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OnR-s6-d4P" userLabel="Site Name Label">
<rect key="frame" x="209" y="310" width="223" height="20"/> <rect key="frame" x="209" y="310" width="223" height="20"/>
@@ -390,7 +434,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" red="0.0" green="0.0" blue="0.0" alpha="0.80000000000000004" colorSpace="calibratedRGB"/> <color key="color" red="0.0" green="0.0" blue="0.0" alpha="0.80000000000000004" colorSpace="calibratedRGB"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Maarten Billemont's password for:" id="1Lb-d0-fQD"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Maarten Billemont's password for:" id="1Lb-d0-fQD">
<font key="font" size="14" name="HelveticaNeue"/> <font key="font" size="14" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -406,7 +449,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" red="0.0" green="0.0" blue="0.0" alpha="0.80000000000000004" colorSpace="calibratedRGB"/> <color key="color" red="0.0" green="0.0" blue="0.0" alpha="0.80000000000000004" colorSpace="calibratedRGB"/>
</shadow> </shadow>
<animations/>
<searchFieldCell key="cell" selectable="YES" editable="YES" focusRingType="none" alignment="center" placeholderString="Site Name" sendsSearchStringImmediately="YES" id="ppl-2c-1E9"> <searchFieldCell key="cell" selectable="YES" editable="YES" focusRingType="none" alignment="center" placeholderString="Site Name" sendsSearchStringImmediately="YES" id="ppl-2c-1E9">
<font key="font" size="36" name="HelveticaNeue-Thin"/> <font key="font" size="36" name="HelveticaNeue-Thin"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -424,7 +466,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.69999999999999996" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="0.69999999999999996" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Type the name of your site (eg. apple.com), then hit enter ⏎ to create a password for it." id="QTI-cz-Onx"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Type the name of your site (eg. apple.com), then hit enter ⏎ to create a password for it." id="QTI-cz-Onx">
<font key="font" size="11" name="HelveticaNeue"/> <font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -443,14 +484,15 @@
</connections> </connections>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rhm-sC-xFS" userLabel="Site Name Tip"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rhm-sC-xFS" userLabel="Site Name Tip">
<rect key="frame" x="37" y="235" width="566" height="15"/> <rect key="frame" x="150" y="220" width="340" height="30"/>
<shadow key="shadow" blurRadius="0.5"> <shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.80000000000000004" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="0.80000000000000004" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="n3W-XU-dya">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Hit enter ⏎ to copy the password, then paste it using ⌘V. Use the arrows ⇅ to navigate the list or esc ⎋ to exit." id="n3W-XU-dya">
<font key="font" size="11" name="HelveticaNeue"/> <font key="font" size="11" name="HelveticaNeue"/>
<string key="title">Hit enter ⏎ to copy the password, hold shift ⇧ to copy the answer.
Use the arrows ⇅ to navigate the list or esc ⎋ to exit.</string>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell> </textFieldCell>
@@ -468,15 +510,14 @@
</connections> </connections>
</textField> </textField>
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="35" horizontalPageScroll="10" verticalLineScroll="35" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="Bme-XK-MMc" userLabel="Sites Table"> <scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="35" horizontalPageScroll="10" verticalLineScroll="35" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="Bme-XK-MMc" userLabel="Sites Table">
<rect key="frame" x="64" y="80" width="512" height="147"/> <rect key="frame" x="64" y="80" width="512" height="132"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="e11-59-xSS"> <clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="e11-59-xSS">
<rect key="frame" x="0.0" y="0.0" width="512" height="147"/> <rect key="frame" x="0.0" y="0.0" width="512" height="132"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="33" rowSizeStyle="automatic" viewBased="YES" floatsGroupRows="NO" id="xvJ-5c-vDp" customClass="MPSitesTableView"> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="33" rowSizeStyle="automatic" viewBased="YES" floatsGroupRows="NO" id="xvJ-5c-vDp" customClass="MPSitesTableView">
<rect key="frame" x="0.0" y="0.0" width="515" height="0.0"/> <rect key="frame" x="0.0" y="0.0" width="515" height="132"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<animations/>
<size key="intercellSpacing" width="3" height="2"/> <size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="deviceWhite"/> <color key="backgroundColor" white="1" alpha="0.0" colorSpace="deviceWhite"/>
<color key="gridColor" name="selectedControlColor" catalog="System" colorSpace="catalog"/> <color key="gridColor" name="selectedControlColor" catalog="System" colorSpace="catalog"/>
@@ -504,7 +545,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.80000000000000004" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="0.80000000000000004" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" alignment="center" title="apple.com" id="o0g-Zv-pH4"> <textFieldCell key="cell" lineBreakMode="truncatingTail" alignment="center" title="apple.com" id="o0g-Zv-pH4">
<font key="font" size="24" name="HelveticaNeue-Thin"/> <font key="font" size="24" name="HelveticaNeue-Thin"/>
<color key="textColor" name="alternateSelectedControlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="alternateSelectedControlTextColor" catalog="System" colorSpace="catalog"/>
@@ -533,7 +573,6 @@
</configuration> </configuration>
</ciFilter> </ciFilter>
</backgroundFilters> </backgroundFilters>
<animations/>
<connections> <connections>
<outlet property="textField" destination="ydd-Rv-tra" id="lMV-D4-Ilq"/> <outlet property="textField" destination="ydd-Rv-tra" id="lMV-D4-Ilq"/>
</connections> </connections>
@@ -549,21 +588,17 @@
</connections> </connections>
</tableView> </tableView>
</subviews> </subviews>
<animations/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/> <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
</clipView> </clipView>
<constraints> <constraints>
<constraint firstAttribute="width" constant="512" id="qfu-pO-SvM"/> <constraint firstAttribute="width" constant="512" id="qfu-pO-SvM"/>
</constraints> </constraints>
<animations/>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="8wr-pu-1lc"> <scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="8wr-pu-1lc">
<rect key="frame" x="-100" y="-100" width="512" height="15"/> <rect key="frame" x="-100" y="-100" width="512" height="15"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<animations/>
</scroller> </scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="mcf-ST-XXI"> <scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="mcf-ST-XXI">
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<animations/>
</scroller> </scroller>
<connections> <connections>
<binding destination="-2" name="hidden" keyPath="locked" id="FF1-c9-zmm"/> <binding destination="-2" name="hidden" keyPath="locked" id="FF1-c9-zmm"/>
@@ -571,7 +606,6 @@
</scrollView> </scrollView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="brI-fg-Kav"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="brI-fg-Kav">
<rect key="frame" x="260" y="45" width="122" height="19"/> <rect key="frame" x="260" y="45" width="122" height="19"/>
<animations/>
<buttonCell key="cell" type="recessed" title="Change Password" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="FQu-fM-NWY" customClass="MPNoStateButtonCell"> <buttonCell key="cell" type="recessed" title="Change Password" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="FQu-fM-NWY" customClass="MPNoStateButtonCell">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/> <font key="font" metaFont="systemBold" size="12"/>
@@ -602,7 +636,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘P" id="MyN-x6-dMk"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘P" id="MyN-x6-dMk">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -640,7 +673,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Click to set a password:" id="gjc-Fw-xa1"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Click to set a password:" id="gjc-Fw-xa1">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -678,7 +710,6 @@
</textField> </textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vES-W5-m4x"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vES-W5-m4x">
<rect key="frame" x="243" y="19" width="155" height="19"/> <rect key="frame" x="243" y="19" width="155" height="19"/>
<animations/>
<buttonCell key="cell" type="recessed" title="Change Password Type" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Fom-sN-EtZ" customClass="MPNoStateButtonCell"> <buttonCell key="cell" type="recessed" title="Change Password Type" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Fom-sN-EtZ" customClass="MPNoStateButtonCell">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/> <font key="font" metaFont="systemBold" size="12"/>
@@ -700,7 +731,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘T" id="HFM-Bk-akx"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘T" id="HFM-Bk-akx">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -725,7 +755,6 @@
</textField> </textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XuF-Sp-6JD"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XuF-Sp-6JD">
<rect key="frame" x="406" y="19" width="80" height="19"/> <rect key="frame" x="406" y="19" width="80" height="19"/>
<animations/>
<buttonCell key="cell" type="recessed" title="Delete Site" bezelStyle="recessed" alignment="center" refusesFirstResponder="YES" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="26m-of-YMQ" customClass="MPNoStateButtonCell"> <buttonCell key="cell" type="recessed" title="Delete Site" bezelStyle="recessed" alignment="center" refusesFirstResponder="YES" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="26m-of-YMQ" customClass="MPNoStateButtonCell">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/> <font key="font" metaFont="systemBold" size="12"/>
@@ -747,7 +776,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘D" id="PPC-be-w4E"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘D" id="PPC-be-w4E">
<font key="font" size="11" name="HelveticaNeue"/> <font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -772,7 +800,6 @@
</textField> </textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1Qo-iG-CQt"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1Qo-iG-CQt">
<rect key="frame" x="126" y="19" width="109" height="19"/> <rect key="frame" x="126" y="19" width="109" height="19"/>
<animations/>
<buttonCell key="cell" type="recessed" title="Set Login Name" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="QFo-9y-aVe" customClass="MPNoStateButtonCell"> <buttonCell key="cell" type="recessed" title="Set Login Name" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="QFo-9y-aVe" customClass="MPNoStateButtonCell">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/> <font key="font" metaFont="systemBold" size="12"/>
@@ -799,7 +826,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘L" id="fUB-rF-7x8"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘L" id="fUB-rF-7x8">
<font key="font" size="11" name="HelveticaNeue"/> <font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -828,7 +854,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Upgrade your site's algorithm version for maximum protection:" id="3ds-qG-YNd"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Upgrade your site's algorithm version for maximum protection:" id="3ds-qG-YNd">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -856,7 +881,6 @@
<subviews> <subviews>
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mcq-qD-yte"> <stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mcq-qD-yte">
<rect key="frame" x="-3" y="-3" width="19" height="27"/> <rect key="frame" x="-3" y="-3" width="19" height="27"/>
<animations/>
<stepperCell key="cell" continuous="YES" alignment="left" minValue="1" maxValue="1000" doubleValue="1" id="73y-03-zHt"/> <stepperCell key="cell" continuous="YES" alignment="left" minValue="1" maxValue="1000" doubleValue="1" id="73y-03-zHt"/>
<connections> <connections>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.algorithmVersion" id="GyA-hK-6cD"/> <binding destination="mcS-ik-b0n" name="value" keyPath="selection.algorithmVersion" id="GyA-hK-6cD"/>
@@ -868,7 +892,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="V1" id="Pjy-Fm-zwB"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="V1" id="Pjy-Fm-zwB">
<font key="font" size="12" name="HelveticaNeue-Medium"/> <font key="font" size="12" name="HelveticaNeue-Medium"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -879,7 +902,6 @@
</connections> </connections>
</textField> </textField>
</subviews> </subviews>
<animations/>
<visibilityPriorities> <visibilityPriorities>
<integer value="1000"/> <integer value="1000"/>
<integer value="1000"/> <integer value="1000"/>
@@ -901,7 +923,6 @@
<subviews> <subviews>
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XgA-Vl-CKh" userLabel="Counter Stepper"> <stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XgA-Vl-CKh" userLabel="Counter Stepper">
<rect key="frame" x="-3" y="-3" width="19" height="27"/> <rect key="frame" x="-3" y="-3" width="19" height="27"/>
<animations/>
<stepperCell key="cell" continuous="YES" alignment="left" minValue="1" maxValue="1000" doubleValue="1" id="ikF-n4-xiI"/> <stepperCell key="cell" continuous="YES" alignment="left" minValue="1" maxValue="1000" doubleValue="1" id="ikF-n4-xiI"/>
<connections> <connections>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.counter" id="qmm-6z-boy"/> <binding destination="mcS-ik-b0n" name="value" keyPath="selection.counter" id="qmm-6z-boy"/>
@@ -913,7 +934,6 @@
<size key="offset" width="0.0" height="1"/> <size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/> <color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow> </shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="1" id="dhQ-bJ-rn3"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="1" id="dhQ-bJ-rn3">
<font key="font" size="12" name="HelveticaNeue-Medium"/> <font key="font" size="12" name="HelveticaNeue-Medium"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -924,7 +944,6 @@
</connections> </connections>
</textField> </textField>
</subviews> </subviews>
<animations/>
<visibilityPriorities> <visibilityPriorities>
<integer value="1000"/> <integer value="1000"/>
<integer value="1000"/> <integer value="1000"/>
@@ -934,6 +953,11 @@
<real value="3.4028234663852886e+38"/> <real value="3.4028234663852886e+38"/>
</customSpacing> </customSpacing>
<connections> <connections>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="9vk-TH-Bm2">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="hidden2" keyPath="selection.generated" previousBinding="9vk-TH-Bm2" id="B6u-H8-b9o"> <binding destination="mcS-ik-b0n" name="hidden2" keyPath="selection.generated" previousBinding="9vk-TH-Bm2" id="B6u-H8-b9o">
<dictionary key="options"> <dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/> <integer key="NSMultipleValuesPlaceholder" value="-1"/>
@@ -943,11 +967,6 @@
<string key="NSValueTransformerName">NSNegateBoolean</string> <string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary> </dictionary>
</binding> </binding>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="9vk-TH-Bm2">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections> </connections>
</stackView> </stackView>
</subviews> </subviews>
@@ -1014,7 +1033,6 @@
<constraint firstItem="gAU-xs-aae" firstAttribute="centerX" secondItem="Aue-Zx-6Mf" secondAttribute="centerX" id="yxU-bl-dmQ"/> <constraint firstItem="gAU-xs-aae" firstAttribute="centerX" secondItem="Aue-Zx-6Mf" secondAttribute="centerX" id="yxU-bl-dmQ"/>
<constraint firstItem="npC-Kk-gUM" firstAttribute="top" secondItem="CnS-iI-dhr" secondAttribute="bottom" constant="8" symbolic="YES" id="zs0-eA-5MW"/> <constraint firstItem="npC-Kk-gUM" firstAttribute="top" secondItem="CnS-iI-dhr" secondAttribute="bottom" constant="8" symbolic="YES" id="zs0-eA-5MW"/>
</constraints> </constraints>
<animations/>
</view> </view>
<point key="canvasLocation" x="-267" y="279"/> <point key="canvasLocation" x="-267" y="279"/>
</window> </window>
@@ -1024,16 +1042,15 @@
<binding destination="-2" name="contentArray" keyPath="sites" id="c96-Dv-HK1"/> <binding destination="-2" name="contentArray" keyPath="sites" id="c96-Dv-HK1"/>
</connections> </connections>
</arrayController> </arrayController>
<box autoresizesSubviews="NO" misplaced="YES" title="Password Types" borderType="line" titlePosition="noTitle" id="bZe-7q-i6q"> <box autoresizesSubviews="NO" title="Password Types" borderType="line" titlePosition="noTitle" id="bZe-7q-i6q">
<rect key="frame" x="0.0" y="0.0" width="416" height="250"/> <rect key="frame" x="0.0" y="0.0" width="416" height="250"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<view key="contentView" id="hAc-y9-IMT"> <view key="contentView" id="hAc-y9-IMT">
<rect key="frame" x="1" y="1" width="414" height="248"/> <rect key="frame" x="1" y="1" width="414" height="248"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<matrix verticalHuggingPriority="750" misplaced="YES" allowsEmptySelection="NO" autorecalculatesCellSize="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3fr-Fd-pxx"> <matrix verticalHuggingPriority="750" allowsEmptySelection="NO" autorecalculatesCellSize="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3fr-Fd-pxx">
<rect key="frame" x="18" y="78" width="378" height="158"/> <rect key="frame" x="18" y="78" width="378" height="158"/>
<animations/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="179" height="18"/> <size key="cellSize" width="179" height="18"/>
<size key="intercellSpacing" width="4" height="2"/> <size key="intercellSpacing" width="4" height="2"/>
@@ -1078,9 +1095,8 @@
</column> </column>
</cells> </cells>
</matrix> </matrix>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kCO-1M-Wz1"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kCO-1M-Wz1">
<rect key="frame" x="16" y="14" width="382" height="56"/> <rect key="frame" x="16" y="14" width="382" height="56"/>
<animations/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="kl0-P1-6ZY"> <textFieldCell key="cell" sendsActionOnEndEditing="YES" id="kl0-P1-6ZY">
<font key="font" metaFont="toolTip"/> <font key="font" metaFont="toolTip"/>
<string key="title">"Personal password" allows you to store your own password. It cannot be regenerated in the event of loss. "Device private password" is similar but will never leave your device: it cannot be synced, backed up or exported.</string> <string key="title">"Personal password" allows you to store your own password. It cannot be regenerated in the event of loss. "Device private password" is similar but will never leave your device: it cannot be synced, backed up or exported.</string>
@@ -1089,7 +1105,6 @@
</textFieldCell> </textFieldCell>
</textField> </textField>
</subviews> </subviews>
<animations/>
</view> </view>
<constraints> <constraints>
<constraint firstItem="kCO-1M-Wz1" firstAttribute="top" secondItem="3fr-Fd-pxx" secondAttribute="bottom" constant="8" symbolic="YES" id="GSx-ci-oqR"/> <constraint firstItem="kCO-1M-Wz1" firstAttribute="top" secondItem="3fr-Fd-pxx" secondAttribute="bottom" constant="8" symbolic="YES" id="GSx-ci-oqR"/>
@@ -1100,13 +1115,12 @@
<constraint firstItem="3fr-Fd-pxx" firstAttribute="leading" secondItem="bZe-7q-i6q" secondAttribute="leading" constant="16" id="w0i-lL-lPE"/> <constraint firstItem="3fr-Fd-pxx" firstAttribute="leading" secondItem="bZe-7q-i6q" secondAttribute="leading" constant="16" id="w0i-lL-lPE"/>
<constraint firstItem="kCO-1M-Wz1" firstAttribute="leading" secondItem="bZe-7q-i6q" secondAttribute="leading" constant="16" id="wBb-UE-BfN"/> <constraint firstItem="kCO-1M-Wz1" firstAttribute="leading" secondItem="bZe-7q-i6q" secondAttribute="leading" constant="16" id="wBb-UE-BfN"/>
</constraints> </constraints>
<animations/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/> <color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="message" size="11"/>
</box> </box>
</objects> </objects>
<resources> <resources>
<image name="icon_gear" width="32" height="32"/>
<image name="small-screen" width="25" height="15.5"/> <image name="small-screen" width="25" height="15.5"/>
</resources> </resources>
</document> </document>

View File

@@ -31,6 +31,8 @@
@property (nonatomic) NSString *typeName; @property (nonatomic) NSString *typeName;
@property (nonatomic) NSString *content; @property (nonatomic) NSString *content;
@property (nonatomic) NSString *displayedContent; @property (nonatomic) NSString *displayedContent;
@property (nonatomic) NSString *question;
@property (nonatomic) NSString *answer;
@property (nonatomic) NSString *loginName; @property (nonatomic) NSString *loginName;
@property (nonatomic) NSNumber *uses; @property (nonatomic) NSNumber *uses;
@property (nonatomic) NSUInteger counter; @property (nonatomic) NSUInteger counter;

View File

@@ -194,13 +194,18 @@
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[self updateContent:[MPSiteEntity existingObjectWithID:_entityOID inContext:context]]; [self updateContent:[MPSiteEntity existingObjectWithID:_entityOID inContext:context]];
}]; }];
else else
PearlNotMainQueue( ^{ PearlNotMainQueue( ^{
NSString *password = [self.algorithm generatePasswordForSiteNamed:self.name ofType:self.type withCounter:self.counter [self updatePasswordWithResult:
usingKey:[MPAppDelegate_Shared get].key]; [self.algorithm generatePasswordForSiteNamed:self.name ofType:self.type withCounter:self.counter
NSString *loginName = [self.algorithm generateLoginForSiteNamed:self.name usingKey:[MPAppDelegate_Shared get].key]; usingKey:[MPAppDelegate_Shared get].key]];
[self updatePasswordWithResult:password]; [self updateLoginNameWithResult:
[self updateLoginNameWithResult:loginName]; [self.algorithm generateLoginForSiteNamed:self.name
usingKey:[MPAppDelegate_Shared get].key]];
[self updateAnswerWithResult:
[self.algorithm generateAnswerForSiteNamed:self.name onQuestion:self.question
usingKey:[MPAppDelegate_Shared get].key]];
} ); } );
} }
@@ -212,6 +217,9 @@
[entity resolveLoginUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) { [entity resolveLoginUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
[self updateLoginNameWithResult:result]; [self updateLoginNameWithResult:result];
}]; }];
[entity resolveSiteAnswerUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
[self updateAnswerWithResult:result];
}];
} }
- (void)updatePasswordWithResult:(NSString *)result { - (void)updatePasswordWithResult:(NSString *)result {
@@ -239,4 +247,11 @@
} ); } );
} }
- (void)updateAnswerWithResult:(NSString *)answer {
PearlMainQueue( ^{
self.answer = answer;
} );
}
@end @end

View File

@@ -37,8 +37,6 @@
DA2CA4F018D323D3007798F8 /* NSArray+Pearl.h in Headers */ = {isa = PBXBuildFile; fileRef = DA2CA4EA18D323D3007798F8 /* NSArray+Pearl.h */; }; DA2CA4F018D323D3007798F8 /* NSArray+Pearl.h in Headers */ = {isa = PBXBuildFile; fileRef = DA2CA4EA18D323D3007798F8 /* NSArray+Pearl.h */; };
DA2CA4F118D323D3007798F8 /* NSTimer+PearlBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2CA4EB18D323D3007798F8 /* NSTimer+PearlBlock.m */; }; DA2CA4F118D323D3007798F8 /* NSTimer+PearlBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2CA4EB18D323D3007798F8 /* NSTimer+PearlBlock.m */; };
DA2CA4F218D323D3007798F8 /* NSTimer+PearlBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = DA2CA4EC18D323D3007798F8 /* NSTimer+PearlBlock.h */; }; DA2CA4F218D323D3007798F8 /* NSTimer+PearlBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = DA2CA4EC18D323D3007798F8 /* NSTimer+PearlBlock.h */; };
DA30E9CE15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA30E9CB15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h */; };
DA30E9CF15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9CC15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m */; };
DA30E9D015722ECA00A68B4C /* Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9CD15722ECA00A68B4C /* Pearl.m */; }; DA30E9D015722ECA00A68B4C /* Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9CD15722ECA00A68B4C /* Pearl.m */; };
DA30E9D215722EE500A68B4C /* Pearl-Crypto.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */; }; DA30E9D215722EE500A68B4C /* Pearl-Crypto.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */; };
DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */ = {isa = PBXBuildFile; fileRef = DA30E9D515723E6900A68B4C /* PearlLazy.h */; }; DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */ = {isa = PBXBuildFile; fileRef = DA30E9D515723E6900A68B4C /* PearlLazy.h */; };
@@ -91,7 +89,6 @@
DA6774451A474A3B004F356A /* mpw-types.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C21A4746AF004F356A /* mpw-types.c */; }; DA6774451A474A3B004F356A /* mpw-types.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C21A4746AF004F356A /* mpw-types.c */; };
DA6774461A474A3B004F356A /* mpw-util.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C51A4746AF004F356A /* mpw-util.c */; }; DA6774461A474A3B004F356A /* mpw-util.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6773C51A4746AF004F356A /* mpw-util.c */; };
DA67744A1A47C8F7004F356A /* mpw-tests-util.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6774481A47C8F7004F356A /* mpw-tests-util.c */; }; DA67744A1A47C8F7004F356A /* mpw-tests-util.c in Sources */ = {isa = PBXBuildFile; fileRef = DA6774481A47C8F7004F356A /* mpw-tests-util.c */; };
DA8495301A915EF400B3053D /* MasterPassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA8495281A915EF400B3053D /* MasterPassword.xcdatamodeld */; };
DA89D4EC1A51EABD00AC64D7 /* Pearl-Cocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = DA89D4EA1A51EABD00AC64D7 /* Pearl-Cocoa.h */; }; DA89D4EC1A51EABD00AC64D7 /* Pearl-Cocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = DA89D4EA1A51EABD00AC64D7 /* Pearl-Cocoa.h */; };
DA89D4ED1A51EABD00AC64D7 /* Pearl-Cocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = DA89D4EB1A51EABD00AC64D7 /* Pearl-Cocoa.m */; }; DA89D4ED1A51EABD00AC64D7 /* Pearl-Cocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = DA89D4EB1A51EABD00AC64D7 /* Pearl-Cocoa.m */; };
DA8ED895192906920099B726 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8ED891192906920099B726 /* PearlTween.m */; }; DA8ED895192906920099B726 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8ED891192906920099B726 /* PearlTween.m */; };
@@ -102,6 +99,7 @@
DA9261521BE1A86700369DE5 /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261501BE1A86700369DE5 /* Fabric.framework */; }; DA9261521BE1A86700369DE5 /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261501BE1A86700369DE5 /* Fabric.framework */; };
DA9261541BE1A88900369DE5 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261531BE1A88900369DE5 /* libc++.tbd */; }; DA9261541BE1A88900369DE5 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261531BE1A88900369DE5 /* libc++.tbd */; };
DA9261561BE1A89600369DE5 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261551BE1A89600369DE5 /* libz.tbd */; }; DA9261561BE1A89600369DE5 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9261551BE1A89600369DE5 /* libz.tbd */; };
DA95B5231C477DE10067F5EF /* MasterPassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA95B51A1C477DE10067F5EF /* MasterPassword.xcdatamodeld */; };
DAAA81B0195A8D1300FA30D9 /* gradient.png in Resources */ = {isa = PBXBuildFile; fileRef = DAAA81AF195A8D1300FA30D9 /* gradient.png */; }; DAAA81B0195A8D1300FA30D9 /* gradient.png in Resources */ = {isa = PBXBuildFile; fileRef = DAAA81AF195A8D1300FA30D9 /* gradient.png */; };
DAADCC4719FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h in Headers */ = {isa = PBXBuildFile; fileRef = DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */; }; DAADCC4719FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h in Headers */ = {isa = PBXBuildFile; fileRef = DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */; };
DAADCC4819FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = DAADCC3F19FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h */; }; DAADCC4819FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = DAADCC3F19FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h */; };
@@ -158,6 +156,7 @@
DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */ = {isa = PBXBuildFile; fileRef = DACA29721705E1A8002C6C22 /* dictionary.lst */; }; DACA29741705E1A8002C6C22 /* dictionary.lst in Resources */ = {isa = PBXBuildFile; fileRef = DACA29721705E1A8002C6C22 /* dictionary.lst */; };
DACA298D1705E2BD002C6C22 /* JRSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA29771705E2BD002C6C22 /* JRSwizzle.h */; }; DACA298D1705E2BD002C6C22 /* JRSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA29771705E2BD002C6C22 /* JRSwizzle.h */; };
DACA299A1705E2BD002C6C22 /* JRSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = DACA298C1705E2BD002C6C22 /* JRSwizzle.m */; }; DACA299A1705E2BD002C6C22 /* JRSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = DACA298C1705E2BD002C6C22 /* JRSwizzle.m */; };
DACBFCDF1C59B22E007EF90F /* NSMutableSet+Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DACBFCDC1C59B22E007EF90F /* NSMutableSet+Pearl.m */; };
DAD9B5F01762CAA4001835F9 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD9B5EF1762CAA4001835F9 /* ServiceManagement.framework */; }; DAD9B5F01762CAA4001835F9 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD9B5EF1762CAA4001835F9 /* ServiceManagement.framework */; };
DAD9B5F11762CAB9001835F9 /* MasterPassword-Mac-LoginHelper.app in Copy LoginHelper */ = {isa = PBXBuildFile; fileRef = DAD9B5E6176299BA001835F9 /* MasterPassword-Mac-LoginHelper.app */; }; DAD9B5F11762CAB9001835F9 /* MasterPassword-Mac-LoginHelper.app in Copy LoginHelper */ = {isa = PBXBuildFile; fileRef = DAD9B5E6176299BA001835F9 /* MasterPassword-Mac-LoginHelper.app */; };
DAEB942E18B47FB3000490CC /* MPInitialWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = DA0933C91747A56A00DE1CEF /* MPInitialWindow.xib */; }; DAEB942E18B47FB3000490CC /* MPInitialWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = DA0933C91747A56A00DE1CEF /* MPInitialWindow.xib */; };
@@ -303,8 +302,6 @@
DA2CA4EA18D323D3007798F8 /* NSArray+Pearl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Pearl.h"; sourceTree = "<group>"; }; DA2CA4EA18D323D3007798F8 /* NSArray+Pearl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Pearl.h"; sourceTree = "<group>"; };
DA2CA4EB18D323D3007798F8 /* NSTimer+PearlBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTimer+PearlBlock.m"; sourceTree = "<group>"; }; DA2CA4EB18D323D3007798F8 /* NSTimer+PearlBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTimer+PearlBlock.m"; sourceTree = "<group>"; };
DA2CA4EC18D323D3007798F8 /* NSTimer+PearlBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTimer+PearlBlock.h"; sourceTree = "<group>"; }; DA2CA4EC18D323D3007798F8 /* NSTimer+PearlBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTimer+PearlBlock.h"; sourceTree = "<group>"; };
DA30E9CB15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+PearlMutableInfo.h"; sourceTree = "<group>"; };
DA30E9CC15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+PearlMutableInfo.m"; sourceTree = "<group>"; };
DA30E9CD15722ECA00A68B4C /* Pearl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pearl.m; sourceTree = "<group>"; }; DA30E9CD15722ECA00A68B4C /* Pearl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pearl.m; sourceTree = "<group>"; };
DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-Crypto.m"; sourceTree = "<group>"; }; DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-Crypto.m"; sourceTree = "<group>"; };
DA30E9D515723E6900A68B4C /* PearlLazy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlLazy.h; sourceTree = "<group>"; }; DA30E9D515723E6900A68B4C /* PearlLazy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlLazy.h; sourceTree = "<group>"; };
@@ -792,13 +789,6 @@
DA831A281A6E1146000AC234 /* mpw-algorithm_v1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v1.c"; sourceTree = "<group>"; }; DA831A281A6E1146000AC234 /* mpw-algorithm_v1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v1.c"; sourceTree = "<group>"; };
DA831A291A6E1146000AC234 /* mpw-algorithm_v2.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v2.c"; sourceTree = "<group>"; }; DA831A291A6E1146000AC234 /* mpw-algorithm_v2.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v2.c"; sourceTree = "<group>"; };
DA831A2A1A6E1146000AC234 /* mpw-algorithm_v3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v3.c"; sourceTree = "<group>"; }; DA831A2A1A6E1146000AC234 /* mpw-algorithm_v3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "mpw-algorithm_v3.c"; sourceTree = "<group>"; };
DA8495291A915EF400B3053D /* MasterPassword 1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 1.xcdatamodel"; sourceTree = "<group>"; };
DA84952A1A915EF400B3053D /* MasterPassword 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 2.xcdatamodel"; sourceTree = "<group>"; };
DA84952B1A915EF400B3053D /* MasterPassword 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 3.xcdatamodel"; sourceTree = "<group>"; };
DA84952C1A915EF400B3053D /* MasterPassword 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 4.xcdatamodel"; sourceTree = "<group>"; };
DA84952D1A915EF400B3053D /* MasterPassword 5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 5.xcdatamodel"; sourceTree = "<group>"; };
DA84952E1A915EF400B3053D /* MasterPassword 6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 6.xcdatamodel"; sourceTree = "<group>"; };
DA84952F1A915EF400B3053D /* MasterPassword 7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 7.xcdatamodel"; sourceTree = "<group>"; };
DA89D4EA1A51EABD00AC64D7 /* Pearl-Cocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Pearl-Cocoa.h"; sourceTree = "<group>"; }; DA89D4EA1A51EABD00AC64D7 /* Pearl-Cocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Pearl-Cocoa.h"; sourceTree = "<group>"; };
DA89D4EB1A51EABD00AC64D7 /* Pearl-Cocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-Cocoa.m"; sourceTree = "<group>"; }; DA89D4EB1A51EABD00AC64D7 /* Pearl-Cocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-Cocoa.m"; sourceTree = "<group>"; };
DA8ED891192906920099B726 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; }; DA8ED891192906920099B726 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; };
@@ -808,6 +798,14 @@
DA9261501BE1A86700369DE5 /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Fabric.framework; sourceTree = "<group>"; }; DA9261501BE1A86700369DE5 /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Fabric.framework; sourceTree = "<group>"; };
DA9261531BE1A88900369DE5 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; DA9261531BE1A88900369DE5 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
DA9261551BE1A89600369DE5 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; DA9261551BE1A89600369DE5 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
DA95B51B1C477DE10067F5EF /* MasterPassword 1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 1.xcdatamodel"; sourceTree = "<group>"; };
DA95B51C1C477DE10067F5EF /* MasterPassword 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 2.xcdatamodel"; sourceTree = "<group>"; };
DA95B51D1C477DE10067F5EF /* MasterPassword 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 3.xcdatamodel"; sourceTree = "<group>"; };
DA95B51E1C477DE10067F5EF /* MasterPassword 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 4.xcdatamodel"; sourceTree = "<group>"; };
DA95B51F1C477DE10067F5EF /* MasterPassword 5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 5.xcdatamodel"; sourceTree = "<group>"; };
DA95B5201C477DE10067F5EF /* MasterPassword 6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 6.xcdatamodel"; sourceTree = "<group>"; };
DA95B5211C477DE10067F5EF /* MasterPassword 7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 7.xcdatamodel"; sourceTree = "<group>"; };
DA95B5221C477DE10067F5EF /* MasterPassword 8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 8.xcdatamodel"; sourceTree = "<group>"; };
DAAA81AF195A8D1300FA30D9 /* gradient.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = gradient.png; sourceTree = "<group>"; }; DAAA81AF195A8D1300FA30D9 /* gradient.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = gradient.png; sourceTree = "<group>"; };
DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+PearlEasyCleanup.h"; sourceTree = "<group>"; }; DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+PearlEasyCleanup.h"; sourceTree = "<group>"; };
DAADCC3F19FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+PearlMigration.h"; sourceTree = "<group>"; }; DAADCC3F19FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+PearlMigration.h"; sourceTree = "<group>"; };
@@ -867,6 +865,8 @@
DACA29721705E1A8002C6C22 /* dictionary.lst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dictionary.lst; sourceTree = "<group>"; }; DACA29721705E1A8002C6C22 /* dictionary.lst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dictionary.lst; sourceTree = "<group>"; };
DACA29771705E2BD002C6C22 /* JRSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JRSwizzle.h; sourceTree = "<group>"; }; DACA29771705E2BD002C6C22 /* JRSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JRSwizzle.h; sourceTree = "<group>"; };
DACA298C1705E2BD002C6C22 /* JRSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JRSwizzle.m; sourceTree = "<group>"; }; DACA298C1705E2BD002C6C22 /* JRSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JRSwizzle.m; sourceTree = "<group>"; };
DACBFCDB1C59B22E007EF90F /* NSMutableSet+Pearl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableSet+Pearl.h"; sourceTree = "<group>"; };
DACBFCDC1C59B22E007EF90F /* NSMutableSet+Pearl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableSet+Pearl.m"; sourceTree = "<group>"; };
DAD0C5F619FD6034009CB08D /* icon_128x128.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_128x128.png; sourceTree = "<group>"; }; DAD0C5F619FD6034009CB08D /* icon_128x128.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_128x128.png; sourceTree = "<group>"; };
DAD0C5F719FD6034009CB08D /* icon_128x128@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_128x128@2x.png"; sourceTree = "<group>"; }; DAD0C5F719FD6034009CB08D /* icon_128x128@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_128x128@2x.png"; sourceTree = "<group>"; };
DAD0C5F819FD6034009CB08D /* icon_16x16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_16x16.png; sourceTree = "<group>"; }; DAD0C5F819FD6034009CB08D /* icon_16x16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_16x16.png; sourceTree = "<group>"; };
@@ -1059,9 +1059,9 @@
DA5E5C7917248AA1003798D8 /* lib */ = { DA5E5C7917248AA1003798D8 /* lib */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DA5E5C8717248AA1003798D8 /* libscryptenc-osx.a */,
DAE8E65319867ADA00416A0F /* libopensslcrypto-osx.a */,
DAEB938518AB0FFD000490CC /* include */, DAEB938518AB0FFD000490CC /* include */,
DAE8E65319867ADA00416A0F /* libopensslcrypto-osx.a */,
DA5E5C8717248AA1003798D8 /* libscryptenc-osx.a */,
); );
path = lib; path = lib;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1070,7 +1070,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DA5E5CB21724A667003798D8 /* Mac */, DA5E5CB21724A667003798D8 /* Mac */,
DA8495281A915EF400B3053D /* MasterPassword.xcdatamodeld */, DA95B51A1C477DE10067F5EF /* MasterPassword.xcdatamodeld */,
DA5E5C971724A667003798D8 /* MPAlgorithm.h */, DA5E5C971724A667003798D8 /* MPAlgorithm.h */,
DA5E5C981724A667003798D8 /* MPAlgorithm.m */, DA5E5C981724A667003798D8 /* MPAlgorithm.m */,
DA5E5C991724A667003798D8 /* MPAlgorithmV0.h */, DA5E5C991724A667003798D8 /* MPAlgorithmV0.h */,
@@ -1798,8 +1798,6 @@
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */, 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */,
DA2CA4EA18D323D3007798F8 /* NSArray+Pearl.h */, DA2CA4EA18D323D3007798F8 /* NSArray+Pearl.h */,
DA2CA4E918D323D3007798F8 /* NSArray+Pearl.m */, DA2CA4E918D323D3007798F8 /* NSArray+Pearl.m */,
DA30E9CB15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h */,
DA30E9CC15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m */,
DAFE4A63150399FF003ABA93 /* NSDateFormatter+RFC3339.h */, DAFE4A63150399FF003ABA93 /* NSDateFormatter+RFC3339.h */,
DAFE4A63150399FF003ABA91 /* NSDateFormatter+RFC3339.m */, DAFE4A63150399FF003ABA91 /* NSDateFormatter+RFC3339.m */,
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */, 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */,
@@ -1808,6 +1806,8 @@
DA2CA4E718D323D3007798F8 /* NSError+PearlFullDescription.m */, DA2CA4E718D323D3007798F8 /* NSError+PearlFullDescription.m */,
DA3B8451190FC86F00246EEA /* NSManagedObject+Pearl.h */, DA3B8451190FC86F00246EEA /* NSManagedObject+Pearl.h */,
DA3B8450190FC86F00246EEA /* NSManagedObject+Pearl.m */, DA3B8450190FC86F00246EEA /* NSManagedObject+Pearl.m */,
DACBFCDB1C59B22E007EF90F /* NSMutableSet+Pearl.h */,
DACBFCDC1C59B22E007EF90F /* NSMutableSet+Pearl.m */,
DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */, DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */,
DAFE45D815039823003ABA7C /* NSObject+PearlExport.h */, DAFE45D815039823003ABA7C /* NSObject+PearlExport.h */,
DAFE45D915039823003ABA7C /* NSObject+PearlExport.m */, DAFE45D915039823003ABA7C /* NSObject+PearlExport.m */,
@@ -1928,7 +1928,6 @@
DAFE4A3615039824003ABA7C /* PearlKeyChain.h in Headers */, DAFE4A3615039824003ABA7C /* PearlKeyChain.h in Headers */,
DAFE4A3815039824003ABA7C /* PearlRSAKey.h in Headers */, DAFE4A3815039824003ABA7C /* PearlRSAKey.h in Headers */,
DAFE4A3A15039824003ABA7C /* PearlSCrypt.h in Headers */, DAFE4A3A15039824003ABA7C /* PearlSCrypt.h in Headers */,
DA30E9CE15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h in Headers */,
DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */, DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */,
DAADCC4719FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h in Headers */, DAADCC4719FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h in Headers */,
DAFE4A63150399FF003ABA88 /* NSObject+PearlKVO.h in Headers */, DAFE4A63150399FF003ABA88 /* NSObject+PearlKVO.h in Headers */,
@@ -2044,6 +2043,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
CLASSPREFIX = MP; CLASSPREFIX = MP;
LastSwiftUpdateCheck = 0720;
LastTestingUpgradeCheck = 0510; LastTestingUpgradeCheck = 0510;
LastUpgradeCheck = 0710; LastUpgradeCheck = 0710;
ORGANIZATIONNAME = Lyndir; ORGANIZATIONNAME = Lyndir;
@@ -2221,7 +2221,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = "/bin/sh -e"; shellPath = "/bin/sh -e";
shellScript = "../../../External/Mac/Crashlytics.framework/run \\\n \"$(/usr/libexec/PlistBuddy -c \"Print :'API Key'\" ../../Resources/Crashlytics/Crashlytics.plist)\" 410fb41450e3a2e50fa8357682d812ecd3e1846f2141a99bdb9d3a6a981ad69c"; shellScript = "../../../External/Mac/Fabric.framework/run \\\n \"$(/usr/libexec/PlistBuddy -c \"Print :'API Key'\" ../../Resources/Crashlytics/Crashlytics.plist)\" 410fb41450e3a2e50fa8357682d812ecd3e1846f2141a99bdb9d3a6a981ad69c";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
@@ -2236,6 +2236,7 @@
DA32CFE519CF1C71004F3F0E /* MPUserEntity.m in Sources */, DA32CFE519CF1C71004F3F0E /* MPUserEntity.m in Sources */,
DA5E5CF71724A667003798D8 /* MPAlgorithmV0.m in Sources */, DA5E5CF71724A667003798D8 /* MPAlgorithmV0.m in Sources */,
DA5E5CF81724A667003798D8 /* MPAlgorithmV1.m in Sources */, DA5E5CF81724A667003798D8 /* MPAlgorithmV1.m in Sources */,
DACBFCDF1C59B22E007EF90F /* NSMutableSet+Pearl.m in Sources */,
DA6774311A4746AF004F356A /* mpw-util.c in Sources */, DA6774311A4746AF004F356A /* mpw-util.c in Sources */,
DA5E5CF91724A667003798D8 /* MPAppDelegate_Key.m in Sources */, DA5E5CF91724A667003798D8 /* MPAppDelegate_Key.m in Sources */,
DA5180CE19FF307E00A587E9 /* MPAppDelegate_Store.m in Sources */, DA5180CE19FF307E00A587E9 /* MPAppDelegate_Store.m in Sources */,
@@ -2257,7 +2258,7 @@
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */, 93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */,
DA32CFDF19CF1C70004F3F0E /* MPSiteEntity.m in Sources */, DA32CFDF19CF1C70004F3F0E /* MPSiteEntity.m in Sources */,
93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */, 93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */,
DA8495301A915EF400B3053D /* MasterPassword.xcdatamodeld in Sources */, DA95B5231C477DE10067F5EF /* MasterPassword.xcdatamodeld in Sources */,
DA6774291A4746AF004F356A /* mpw-algorithm.c in Sources */, DA6774291A4746AF004F356A /* mpw-algorithm.c in Sources */,
93D395E4830290EBB6E71F34 /* MPNoStateButton.m in Sources */, 93D395E4830290EBB6E71F34 /* MPNoStateButton.m in Sources */,
DA4DAE941A7D8117003E5423 /* MPAlgorithmV3.m in Sources */, DA4DAE941A7D8117003E5423 /* MPAlgorithmV3.m in Sources */,
@@ -2319,7 +2320,6 @@
DAFE4A3915039824003ABA7C /* PearlRSAKey.m in Sources */, DAFE4A3915039824003ABA7C /* PearlRSAKey.m in Sources */,
DAFE4A3B15039824003ABA7C /* PearlSCrypt.m in Sources */, DAFE4A3B15039824003ABA7C /* PearlSCrypt.m in Sources */,
DA8ED895192906920099B726 /* PearlTween.m in Sources */, DA8ED895192906920099B726 /* PearlTween.m in Sources */,
DA30E9CF15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m in Sources */,
DA2CA4F118D323D3007798F8 /* NSTimer+PearlBlock.m in Sources */, DA2CA4F118D323D3007798F8 /* NSTimer+PearlBlock.m in Sources */,
DA3B8452190FC86F00246EEA /* NSManagedObject+Pearl.m in Sources */, DA3B8452190FC86F00246EEA /* NSManagedObject+Pearl.m in Sources */,
DA30E9D015722ECA00A68B4C /* Pearl.m in Sources */, DA30E9D015722ECA00A68B4C /* Pearl.m in Sources */,
@@ -2562,6 +2562,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = MasterPassword.entitlements; CODE_SIGN_ENTITLEMENTS = MasterPassword.entitlements;
CODE_SIGN_IDENTITY = "Mac Developer"; CODE_SIGN_IDENTITY = "Mac Developer";
@@ -2572,6 +2573,7 @@
); );
GCC_PREFIX_HEADER = "MasterPassword-Prefix.pch"; GCC_PREFIX_HEADER = "MasterPassword-Prefix.pch";
INFOPLIST_FILE = "MasterPassword-Info.plist"; INFOPLIST_FILE = "MasterPassword-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"/Users/lhunath/Documents/workspace/lyndir/MasterPassword/External/Pearl/Pearl-Crypto/lib", "/Users/lhunath/Documents/workspace/lyndir/MasterPassword/External/Pearl/Pearl-Crypto/lib",
@@ -2579,6 +2581,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.lyndir.lhunath.MasterPassword.Mac; PRODUCT_BUNDLE_IDENTIFIER = com.lyndir.lhunath.MasterPassword.Mac;
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
SKIP_INSTALL = NO; SKIP_INSTALL = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
WRAPPER_NAME = "Master Password.${WRAPPER_EXTENSION}"; WRAPPER_NAME = "Master Password.${WRAPPER_EXTENSION}";
}; };
name = "Debug-Mac"; name = "Debug-Mac";
@@ -2587,6 +2590,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = MasterPassword.entitlements; CODE_SIGN_ENTITLEMENTS = MasterPassword.entitlements;
CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_IDENTITY = "Developer ID Application";
@@ -2597,6 +2601,7 @@
); );
GCC_PREFIX_HEADER = "MasterPassword-Prefix.pch"; GCC_PREFIX_HEADER = "MasterPassword-Prefix.pch";
INFOPLIST_FILE = "MasterPassword-Info.plist"; INFOPLIST_FILE = "MasterPassword-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"/Users/lhunath/Documents/workspace/lyndir/MasterPassword/External/Pearl/Pearl-Crypto/lib", "/Users/lhunath/Documents/workspace/lyndir/MasterPassword/External/Pearl/Pearl-Crypto/lib",
@@ -2739,6 +2744,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = MasterPassword.entitlements; CODE_SIGN_ENTITLEMENTS = MasterPassword.entitlements;
CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application";
@@ -2749,6 +2755,7 @@
); );
GCC_PREFIX_HEADER = "MasterPassword-Prefix.pch"; GCC_PREFIX_HEADER = "MasterPassword-Prefix.pch";
INFOPLIST_FILE = "MasterPassword-Info.plist"; INFOPLIST_FILE = "MasterPassword-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"/Users/lhunath/Documents/workspace/lyndir/MasterPassword/External/Pearl/Pearl-Crypto/lib", "/Users/lhunath/Documents/workspace/lyndir/MasterPassword/External/Pearl/Pearl-Crypto/lib",
@@ -2946,18 +2953,19 @@
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCVersionGroup section */ /* Begin XCVersionGroup section */
DA8495281A915EF400B3053D /* MasterPassword.xcdatamodeld */ = { DA95B51A1C477DE10067F5EF /* MasterPassword.xcdatamodeld */ = {
isa = XCVersionGroup; isa = XCVersionGroup;
children = ( children = (
DA8495291A915EF400B3053D /* MasterPassword 1.xcdatamodel */, DA95B51B1C477DE10067F5EF /* MasterPassword 1.xcdatamodel */,
DA84952A1A915EF400B3053D /* MasterPassword 2.xcdatamodel */, DA95B51C1C477DE10067F5EF /* MasterPassword 2.xcdatamodel */,
DA84952B1A915EF400B3053D /* MasterPassword 3.xcdatamodel */, DA95B51D1C477DE10067F5EF /* MasterPassword 3.xcdatamodel */,
DA84952C1A915EF400B3053D /* MasterPassword 4.xcdatamodel */, DA95B51E1C477DE10067F5EF /* MasterPassword 4.xcdatamodel */,
DA84952D1A915EF400B3053D /* MasterPassword 5.xcdatamodel */, DA95B51F1C477DE10067F5EF /* MasterPassword 5.xcdatamodel */,
DA84952E1A915EF400B3053D /* MasterPassword 6.xcdatamodel */, DA95B5201C477DE10067F5EF /* MasterPassword 6.xcdatamodel */,
DA84952F1A915EF400B3053D /* MasterPassword 7.xcdatamodel */, DA95B5211C477DE10067F5EF /* MasterPassword 7.xcdatamodel */,
DA95B5221C477DE10067F5EF /* MasterPassword 8.xcdatamodel */,
); );
currentVersion = DA84952F1A915EF400B3053D /* MasterPassword 7.xcdatamodel */; currentVersion = DA95B5221C477DE10067F5EF /* MasterPassword 8.xcdatamodel */;
path = MasterPassword.xcdatamodeld; path = MasterPassword.xcdatamodeld;
sourceTree = "<group>"; sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel; versionGroupType = wrapper.xcdatamodel;

View File

@@ -28,42 +28,80 @@
#import <CoreFoundation/CFString.h> #import <CoreFoundation/CFString.h>
#import <objc/runtime.h> #import <objc/runtime.h>
#import <objc/message.h> #import <objc/message.h>
#import <objc/NSObjCRuntime.h>
#import <stdlib.h>
#define trc(format, ...) objc_msgSend( \ #define trc(format, ...) \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ do { \
sel_getUid( "inFile:atLine:trc:" ), \ char *_msg = NULL; \
basename( (char *)__FILE__ ), __LINE__, \ asprintf( &_msg, format, ##__VA_ARGS__ ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
##__VA_ARGS__) _sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
#define dbg(format, ...) objc_msgSend( \ sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
sel_getUid( "inFile:atLine:dbg:" ), \ CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 0, \
basename( (char *)__FILE__ ), __LINE__, \ CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ } while (0)
##__VA_ARGS__)
#define inf(format, ...) objc_msgSend( \ #define dbg(format, ...) \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ do { \
sel_getUid( "inFile:atLine:inf:" ), \ char *_msg = NULL; \
basename( (char *)__FILE__ ), __LINE__, \ asprintf( &_msg, format, ##__VA_ARGS__ ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
##__VA_ARGS__) _sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
#define wrn(format, ...) objc_msgSend( \ sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
sel_getUid( "inFile:atLine:wrn:" ), \ CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 1, \
basename( (char *)__FILE__ ), __LINE__, \ CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ } while (0)
##__VA_ARGS__)
#define err(format, ...) objc_msgSend( \ #define inf(format, ...) \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ do { \
sel_getUid( "inFile:atLine:err:" ), \ char *_msg = NULL; \
basename( (char *)__FILE__ ), __LINE__, \ asprintf( &_msg, format, ##__VA_ARGS__ ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
##__VA_ARGS__) _sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
#define ftl(format, ...) do{objc_msgSend( \ sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
sel_getUid( "inFile:atLine:ftl:" ), \ CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 2, \
basename( (char *)__FILE__ ), __LINE__, \ CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ } while (0)
##__VA_ARGS__); abort(); } while (0)
#define wrn(format, ...) \
do { \
char *_msg = NULL; \
asprintf( &_msg, format, ##__VA_ARGS__ ); \
void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
_sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 3, \
CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
} while (0)
#define err(format, ...) \
do { \
char *_msg = NULL; \
asprintf( &_msg, format, ##__VA_ARGS__ ); \
void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
_sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 4, \
CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
} while (0)
#define ftl(format, ...) \
do { \
char *_msg = NULL; \
asprintf( &_msg, format, ##__VA_ARGS__ ); \
void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
_sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 5, \
CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
abort(); \
} while (0)
#endif #endif

View File

@@ -3,6 +3,6 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>_XCCurrentVersionName</key> <key>_XCCurrentVersionName</key>
<string>MasterPassword 7.xcdatamodel</string> <string>MasterPassword 8.xcdatamodel</string>
</dict> </dict>
</plist> </plist>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="9525" systemVersion="15C50" minimumToolsVersion="Automatic">
<entity name="MPGeneratedSiteEntity" representedClassName="MPGeneratedSiteEntity" parentEntity="MPSiteEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity>
<entity name="MPSiteEntity" representedClassName="MPSiteEntity" isAbstract="YES" elementID="58EE245C-6827-4C11-BB7E-5722F2426EC2" syncable="YES">
<attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
<attribute name="lastUsed" attributeType="Date" indexed="YES" syncable="YES"/>
<attribute name="loginGenerated_" attributeType="Boolean" defaultValueString="NO" syncable="YES"/>
<attribute name="loginName" optional="YES" attributeType="String" elementID="A1B9F981-D33C-4BFE-9F94-C9D3E1F78E51" syncable="YES"/>
<attribute name="name" attributeType="String" minValueString="1" indexed="YES" syncable="YES"/>
<attribute name="requiresExplicitMigration_" attributeType="Boolean" defaultValueString="NO">
<userInfo/>
</attribute>
<attribute name="type_" attributeType="Integer 16" defaultValueString="17" syncable="YES"/>
<attribute name="uses_" attributeType="Integer 16" defaultValueString="0" indexed="YES" syncable="YES"/>
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/>
<relationship name="questions" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="MPSiteQuestionEntity" inverseName="site" inverseEntity="MPSiteQuestionEntity" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="sites" inverseEntity="MPUserEntity" elementID="FC8AE32E-7BE3-4FA6-8611-B7DC0DB063EF" syncable="YES"/>
</entity>
<entity name="MPSiteQuestionEntity" representedClassName="MPSiteQuestionEntity" syncable="YES">
<attribute name="keyword" attributeType="String" syncable="YES"/>
<relationship name="site" maxCount="1" deletionRule="Nullify" destinationEntity="MPSiteEntity" inverseName="questions" inverseEntity="MPSiteEntity" syncable="YES"/>
</entity>
<entity name="MPStoredSiteEntity" representedClassName="MPStoredSiteEntity" parentEntity="MPSiteEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES">
<attribute name="avatar_" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
<attribute name="defaultType_" attributeType="Integer 16" defaultValueString="17" syncable="YES"/>
<attribute name="keyID" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="lastUsed" optional="YES" attributeType="Date" syncable="YES"/>
<attribute name="name" attributeType="String" syncable="YES"/>
<attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO">
<userInfo/>
</attribute>
<attribute name="touchID_" attributeType="Boolean" defaultValueString="0">
<userInfo/>
</attribute>
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="2" syncable="YES"/>
<relationship name="sites" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPSiteEntity" inverseName="user" inverseEntity="MPSiteEntity" elementID="D18D6772-040E-4CFE-8F32-A34B08E9E9BC" syncable="YES"/>
</entity>
<elements>
<element name="MPGeneratedSiteEntity" positionX="216" positionY="-288" width="128" height="58"/>
<element name="MPSiteEntity" positionX="-0" positionY="-286" width="128" height="208"/>
<element name="MPSiteQuestionEntity" positionX="-2" positionY="-9" width="128" height="73"/>
<element name="MPStoredSiteEntity" positionX="214" positionY="-171" width="128" height="58"/>
<element name="MPUserEntity" positionX="-218" positionY="-288" width="128" height="178"/>
</elements>
</model>

View File

@@ -178,7 +178,7 @@
else if ([cell isKindOfClass:[MPSendAnswersCell class]]) { else if ([cell isKindOfClass:[MPSendAnswersCell class]]) {
NSString *body; NSString *body;
if (!_multiple) { if (!_multiple) {
NSObject *answer = [site.algorithm resolveAnswerForSite:site usingKey:[MPiOSAppDelegate get].key]; NSObject *answer = [site resolveSiteAnswerUsingKey:[MPiOSAppDelegate get].key];
body = strf( @"Master Password generated the following security answer for your site: %@\n\n" body = strf( @"Master Password generated the following security answer for your site: %@\n\n"
@"%@\n" @"%@\n"
@"\n\nYou should use this as the answer to each security question the site asks you.\n" @"\n\nYou should use this as the answer to each security question the site asks you.\n"
@@ -188,7 +188,7 @@
NSMutableString *bodyBuilder = [NSMutableString string]; NSMutableString *bodyBuilder = [NSMutableString string];
[bodyBuilder appendFormat:@"Master Password generated the following security answers for your site: %@\n\n", site.name]; [bodyBuilder appendFormat:@"Master Password generated the following security answers for your site: %@\n\n", site.name];
for (MPSiteQuestionEntity *question in site.questions) { for (MPSiteQuestionEntity *question in site.questions) {
NSObject *answer = [site.algorithm resolveAnswerForQuestion:question usingKey:[MPiOSAppDelegate get].key]; NSObject *answer = [question resolveQuestionAnswerUsingKey:[MPiOSAppDelegate get].key];
[bodyBuilder appendFormat:@"For question: '%@', use answer: %@\n", question.keyword, answer]; [bodyBuilder appendFormat:@"For question: '%@', use answer: %@\n", question.keyword, answer];
} }
[bodyBuilder appendFormat:@"\n\nUse the answer for the matching security question.\n" [bodyBuilder appendFormat:@"\n\nUse the answer for the matching security question.\n"
@@ -241,7 +241,7 @@
self.titleLabel.text = strl( @"Answer for %@:", site.name ); self.titleLabel.text = strl( @"Answer for %@:", site.name );
self.answerField.text = @"..."; self.answerField.text = @"...";
[site.algorithm resolveAnswerForSite:site usingKey:[MPiOSAppDelegate get].key result:^(NSString *result) { [site resolveSiteAnswerUsingKey:[MPiOSAppDelegate get].key result:^(NSString *result) {
PearlMainQueue( ^{ PearlMainQueue( ^{
self.answerField.text = result; self.answerField.text = result;
} ); } );
@@ -330,7 +330,7 @@
PearlMainQueue( ^{ PearlMainQueue( ^{
self.answerField.text = @"..."; self.answerField.text = @"...";
} ); } );
[site.algorithm resolveAnswerForQuestion:question usingKey:[MPiOSAppDelegate get].key result:^(NSString *result) { [question resolveQuestionAnswerUsingKey:[MPiOSAppDelegate get].key result:^(NSString *result) {
PearlMainQueue( ^{ PearlMainQueue( ^{
self.questionField.text = keyword; self.questionField.text = keyword;
self.answerField.text = result; self.answerField.text = result;

View File

@@ -33,7 +33,7 @@ typedef NS_ENUM(NSUInteger, MPAvatarMode) {
@interface MPAvatarCell : UICollectionViewCell @interface MPAvatarCell : UICollectionViewCell
@property (copy, nonatomic) NSString *name; @property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) long avatar; @property (assign, nonatomic) NSUInteger avatar;
@property (assign, nonatomic) MPAvatarMode mode; @property (assign, nonatomic) MPAvatarMode mode;
@property (assign, nonatomic) CGFloat visibility; @property (assign, nonatomic) CGFloat visibility;
@property (assign, nonatomic) BOOL spinnerActive; @property (assign, nonatomic) BOOL spinnerActive;

View File

@@ -111,7 +111,7 @@ const long MPAvatarAdd = 10000;
#pragma mark - Properties #pragma mark - Properties
- (void)setAvatar:(long)avatar { - (void)setAvatar:(NSUInteger)avatar {
_avatar = avatar == MPAvatarAdd? MPAvatarAdd: (avatar + MPAvatarCount) % MPAvatarCount; _avatar = avatar == MPAvatarAdd? MPAvatarAdd: (avatar + MPAvatarCount) % MPAvatarCount;
@@ -121,7 +121,7 @@ const long MPAvatarAdd = 10000;
_newUser = YES; _newUser = YES;
} }
else else
self.avatarImageView.image = [UIImage imageNamed:strf( @"avatar-%ld", _avatar )]; self.avatarImageView.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)_avatar )];
} }
- (NSString *)name { - (NSString *)name {

View File

@@ -12,6 +12,7 @@
@interface MPPreferencesViewController : UITableViewController @interface MPPreferencesViewController : UITableViewController
@property(weak, nonatomic) IBOutlet UISwitch *savePasswordSwitch; @property(weak, nonatomic) IBOutlet UISwitch *savePasswordSwitch;
@property(weak, nonatomic) IBOutlet UISwitch *touchIDSwitch;
@property(weak, nonatomic) IBOutlet UITableViewCell *signOutCell; @property(weak, nonatomic) IBOutlet UITableViewCell *signOutCell;
@property(weak, nonatomic) IBOutlet UITableViewCell *feedbackCell; @property(weak, nonatomic) IBOutlet UITableViewCell *feedbackCell;
@property(weak, nonatomic) IBOutlet UITableViewCell *showHelpCell; @property(weak, nonatomic) IBOutlet UITableViewCell *showHelpCell;

View File

@@ -12,7 +12,7 @@
#import "MPAppDelegate_Store.h" #import "MPAppDelegate_Store.h"
#import "UIColor+Expanded.h" #import "UIColor+Expanded.h"
#import "MPPasswordsViewController.h" #import "MPPasswordsViewController.h"
#import "MPCoachmarkViewController.h" #import "MPAppDelegate_InApp.h"
@interface MPPreferencesViewController() @interface MPPreferencesViewController()
@@ -25,6 +25,10 @@
[super viewDidLoad]; [super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor]; self.view.backgroundColor = [UIColor clearColor];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 100;
self.tableView.contentInset = UIEdgeInsetsMake( 64, 0, 49, 0 );
} }
- (void)viewWillAppear:(BOOL)animated { - (void)viewWillAppear:(BOOL)animated {
@@ -35,13 +39,18 @@
if (![[NSUserDefaults standardUserDefaults] synchronize]) if (![[NSUserDefaults standardUserDefaults] synchronize])
wrn( @"Couldn't synchronize after preferences appearance." ); wrn( @"Couldn't synchronize after preferences appearance." );
[self reload];
}
- (void)reload {
MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserForMainThread]; MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserForMainThread];
self.generatedTypeControl.selectedSegmentIndex = [self generatedSegmentIndexForType:activeUser.defaultType]; self.generatedTypeControl.selectedSegmentIndex = [self generatedSegmentIndexForType:activeUser.defaultType];
self.storedTypeControl.selectedSegmentIndex = [self storedSegmentIndexForType:activeUser.defaultType]; self.storedTypeControl.selectedSegmentIndex = [self storedSegmentIndexForType:activeUser.defaultType];
self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%ld", (long)activeUser.avatar )]; self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)activeUser.avatar )];
self.savePasswordSwitch.on = activeUser.saveKey; self.savePasswordSwitch.on = activeUser.saveKey;
self.touchIDSwitch.on = activeUser.touchID;
self.tableView.contentInset = UIEdgeInsetsMake( 64, 0, 49, 0 ); self.touchIDSwitch.enabled = self.savePasswordSwitch.on && [[MPiOSAppDelegate get] isFeatureUnlocked:MPProductTouchID];
} }
#pragma mark - UITableViewDelegate #pragma mark - UITableViewDelegate
@@ -57,6 +66,11 @@
return cell; return cell;
} }
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
@@ -96,6 +110,24 @@
else else
[[MPiOSAppDelegate get] forgetSavedKeyFor:activeUser]; [[MPiOSAppDelegate get] forgetSavedKeyFor:activeUser];
[context saveToStore]; [context saveToStore];
PearlMainQueue(^{
[self reload];
});
}];
if (sender == self.touchIDSwitch)
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserInContext:context];
if ((activeUser.touchID = self.touchIDSwitch.on))
[[MPiOSAppDelegate get] storeSavedKeyFor:activeUser];
else
[[MPiOSAppDelegate get] forgetSavedKeyFor:activeUser];
[context saveToStore];
PearlMainQueue( ^{
[self reload];
} );
}]; }];
if (sender == self.generatedTypeControl || sender == self.storedTypeControl) { if (sender == self.generatedTypeControl || sender == self.storedTypeControl) {
@@ -104,13 +136,13 @@
else if (sender == self.storedTypeControl) else if (sender == self.storedTypeControl)
self.generatedTypeControl.selectedSegmentIndex = -1; self.generatedTypeControl.selectedSegmentIndex = -1;
MPSiteType defaultType = [self typeForSelectedSegment];
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteType defaultType = [[MPiOSAppDelegate get] activeUserInContext:context].defaultType = [self typeForSelectedSegment]; [[MPiOSAppDelegate get] activeUserInContext:context].defaultType = defaultType;
[context saveToStore]; [context saveToStore];
PearlMainQueue( ^{ PearlMainQueue( ^{
self.generatedTypeControl.selectedSegmentIndex = [self generatedSegmentIndexForType:defaultType]; [self reload];
self.storedTypeControl.selectedSegmentIndex = [self storedSegmentIndexForType:defaultType];
} ); } );
}]; }];
} }
@@ -123,9 +155,9 @@
activeUser.avatar = (activeUser.avatar - 1 + MPAvatarCount) % MPAvatarCount; activeUser.avatar = (activeUser.avatar - 1 + MPAvatarCount) % MPAvatarCount;
[context saveToStore]; [context saveToStore];
long avatar = activeUser.avatar; NSUInteger avatar = activeUser.avatar;
PearlMainQueue( ^{ PearlMainQueue( ^{
self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%ld", avatar )]; self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)avatar )];
} ); } );
}]; }];
} }
@@ -137,9 +169,9 @@
activeUser.avatar = (activeUser.avatar + 1 + MPAvatarCount) % MPAvatarCount; activeUser.avatar = (activeUser.avatar + 1 + MPAvatarCount) % MPAvatarCount;
[context saveToStore]; [context saveToStore];
long avatar = activeUser.avatar; NSUInteger avatar = activeUser.avatar;
PearlMainQueue( ^{ PearlMainQueue( ^{
self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%ld", avatar )]; self.avatarImage.image = [UIImage imageNamed:strf( @"avatar-%lu", (unsigned long)avatar )];
} ); } );
}]; }];
} }

View File

@@ -28,7 +28,8 @@ PearlEnum( MPDevelopmentFuelConsumption,
NSMutableString *features = [NSMutableString string]; NSMutableString *features = [NSMutableString string];
NSArray *storeVersions = @[ NSArray *storeVersions = @[
@"Generated Usernames\nSecurity Question Answers" @"Generated Usernames\nSecurity Question Answers",
@"TouchID Support"
]; ];
NSInteger storeVersion = [[NSUserDefaults standardUserDefaults] integerForKey:@"storeVersion"]; NSInteger storeVersion = [[NSUserDefaults standardUserDefaults] integerForKey:@"storeVersion"];
for (; storeVersion < [storeVersions count]; ++storeVersion) for (; storeVersion < [storeVersions count]; ++storeVersion)
@@ -51,6 +52,8 @@ PearlEnum( MPDevelopmentFuelConsumption,
self.tableView.tableHeaderView = [UIView new]; self.tableView.tableHeaderView = [UIView new];
self.tableView.tableFooterView = [UIView new]; self.tableView.tableFooterView = [UIView new];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 400;
self.view.backgroundColor = [UIColor clearColor]; self.view.backgroundColor = [UIColor clearColor];
} }
@@ -89,18 +92,6 @@ PearlEnum( MPDevelopmentFuelConsumption,
- (MPStoreProductCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - (MPStoreProductCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MPStoreProductCell *cell = (MPStoreProductCell *)[super tableView:tableView cellForRowAtIndexPath:indexPath]; MPStoreProductCell *cell = (MPStoreProductCell *)[super tableView:tableView cellForRowAtIndexPath:indexPath];
if (cell.contentView.translatesAutoresizingMaskIntoConstraints) {
cell.contentView.translatesAutoresizingMaskIntoConstraints = NO;
[cell addConstraints:@[
[NSLayoutConstraint constraintWithItem:cell attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:cell.contentView attribute:NSLayoutAttributeTop multiplier:1 constant:0],
[NSLayoutConstraint constraintWithItem:cell attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual
toItem:cell.contentView attribute:NSLayoutAttributeRight multiplier:1 constant:0],
[NSLayoutConstraint constraintWithItem:cell attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual
toItem:cell.contentView attribute:NSLayoutAttributeLeft multiplier:1 constant:0],
]];
}
if (indexPath.section == 0) if (indexPath.section == 0)
cell.selectionStyle = [[MPiOSAppDelegate get] isFeatureUnlocked:[self productForCell:cell].productIdentifier]? cell.selectionStyle = [[MPiOSAppDelegate get] isFeatureUnlocked:[self productForCell:cell].productIdentifier]?
UITableViewCellSelectionStyleNone: UITableViewCellSelectionStyleDefault; UITableViewCellSelectionStyleNone: UITableViewCellSelectionStyleDefault;
@@ -122,11 +113,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; return UITableViewAutomaticDimension;
[cell layoutIfNeeded];
[cell layoutIfNeeded];
dbg_return_tr( cell.contentView.bounds.size.height, @, indexPath );
} }
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

View File

@@ -147,12 +147,13 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
case MPActiveUserStateLogin: { case MPActiveUserStateLogin: {
self.entryField.enabled = NO; self.entryField.enabled = NO;
[self selectedAvatar].spinnerActive = YES; [self selectedAvatar].spinnerActive = YES;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { NSString *masterPassword = self.entryField.text;
if (![MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
BOOL signedIn = NO, isNew = NO; BOOL signedIn = NO, isNew = NO;
MPUserEntity *user = [self selectedUserInContext:context isNew:&isNew]; MPUserEntity *user = [self selectedUserInContext:context isNew:&isNew];
if (!isNew && user) if (!isNew && user)
signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context
usingMasterPassword:self.entryField.text]; usingMasterPassword:masterPassword];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ [[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.entryField.text = @""; self.entryField.text = @"";
@@ -165,7 +166,10 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
return; return;
} }
}]; }];
}]; }]) {
self.entryField.enabled = YES;
[self selectedAvatar].spinnerActive = NO;
}
break; break;
} }
case MPActiveUserStateUserName: { case MPActiveUserStateUserName: {
@@ -209,21 +213,24 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
self.entryField.enabled = NO; self.entryField.enabled = NO;
MPAvatarCell *avatarCell = [self selectedAvatar]; MPAvatarCell *avatarCell = [self selectedAvatar];
avatarCell.spinnerActive = YES; avatarCell.spinnerActive = YES;
NSUInteger newUserAvatar = avatarCell.avatar;
NSString *newUserName = avatarCell.name;
if (![MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { if (![MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
BOOL isNew = NO; BOOL isNew = NO;
MPUserEntity *user = [self userForAvatar:avatarCell inContext:context isNew:&isNew]; MPUserEntity *user = [self userForAvatar:avatarCell inContext:context isNew:&isNew];
if (isNew) { if (isNew) {
user = [MPUserEntity insertNewObjectInContext:context]; user = [MPUserEntity insertNewObjectInContext:context];
user.algorithm = MPAlgorithmDefault; user.algorithm = MPAlgorithmDefault;
user.avatar = avatarCell.avatar; user.avatar = newUserAvatar;
user.name = avatarCell.name; user.name = newUserName;
} }
BOOL signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context usingMasterPassword:masterPassword]; BOOL signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context
usingMasterPassword:masterPassword];
PearlMainQueue( ^{ PearlMainQueue( ^{
self.entryField.text = @""; self.entryField.text = @"";
self.entryField.enabled = YES; self.entryField.enabled = YES;
[self selectedAvatar].spinnerActive = NO; avatarCell.spinnerActive = NO;
if (!signedIn) { if (!signedIn) {
// Sign in failed, shouldn't happen for a new user. // Sign in failed, shouldn't happen for a new user.
@@ -232,8 +239,10 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
return; return;
} }
} ); } );
}]) }]) {
self.entryField.enabled = YES;
avatarCell.spinnerActive = NO; avatarCell.spinnerActive = NO;
}
break; break;
} }
@@ -356,16 +365,27 @@ referenceSizeForFooterInSection:(NSInteger)section {
self.activeUserState = MPActiveUserStateLogin; self.activeUserState = MPActiveUserStateLogin;
self.entryField.enabled = NO; self.entryField.enabled = NO;
[self selectedAvatar].spinnerActive = YES; MPAvatarCell *userAvatar = [self selectedAvatar];
BOOL signedIn = NO; userAvatar.spinnerActive = YES;
if (!isNew && mainUser) if (!isNew && mainUser && [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
signedIn = [[MPiOSAppDelegate get] signInAsUser:mainUser saveInContext:mainContext usingMasterPassword:nil]; MPUserEntity *user = [MPUserEntity existingObjectWithID:mainUser.objectID inContext:context];
BOOL signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:mainContext usingMasterPassword:nil];
PearlMainQueue(^{
self.entryField.text = @"";
self.entryField.enabled = YES;
userAvatar.spinnerActive = NO;
if (!signedIn)
[self.entryField becomeFirstResponder];
});
}])
return;
self.entryField.text = @""; self.entryField.text = @"";
self.entryField.enabled = YES; self.entryField.enabled = YES;
[self selectedAvatar].spinnerActive = NO; userAvatar.spinnerActive = NO;
if (!signedIn)
[self.entryField becomeFirstResponder]; [self.entryField becomeFirstResponder];
} }
} }

View File

@@ -36,8 +36,8 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
@try { @try {
[[NSBundle mainBundle] mutableInfoDictionary][@"CFBundleDisplayName"] = @"Master Password"; // [[NSBundle mainBundle] mutableInfoDictionary][@"CFBundleDisplayName"] = @"Master Password";
[[NSBundle mainBundle] mutableLocalizedInfoDictionary][@"CFBundleDisplayName"] = @"Master Password"; // [[NSBundle mainBundle] mutableLocalizedInfoDictionary][@"CFBundleDisplayName"] = @"Master Password";
#ifdef CRASHLYTICS #ifdef CRASHLYTICS
NSString *crashlyticsAPIKey = [self crashlyticsAPIKey]; NSString *crashlyticsAPIKey = [self crashlyticsAPIKey];

View File

@@ -20,7 +20,7 @@
NSStringFromSelector( @selector( helpHidden ) ) : @NO, NSStringFromSelector( @selector( helpHidden ) ) : @NO,
NSStringFromSelector( @selector( siteInfoHidden ) ) : @YES, NSStringFromSelector( @selector( siteInfoHidden ) ) : @YES,
NSStringFromSelector( @selector( showSetup ) ) : @YES, NSStringFromSelector( @selector( showSetup ) ) : @YES,
NSStringFromSelector( @selector( iTunesID ) ) : @"510296984", NSStringFromSelector( @selector( appleID ) ) : @"510296984",
NSStringFromSelector( @selector( actionsTipShown ) ) : @(!self.firstRun), NSStringFromSelector( @selector( actionsTipShown ) ) : @(!self.firstRun),
NSStringFromSelector( @selector( typeTipShown ) ) : @(!self.firstRun), NSStringFromSelector( @selector( typeTipShown ) ) : @(!self.firstRun),
NSStringFromSelector( @selector( loginNameTipShown ) ) : @NO, NSStringFromSelector( @selector( loginNameTipShown ) ) : @NO,

View File

@@ -60,7 +60,7 @@
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>Copyright © 2011-2014 Lyndir</string> <string>© 2011-2016 Lyndir</string>
<key>UIAppFonts</key> <key>UIAppFonts</key>
<array> <array>
<string>Exo2.0-Bold.otf</string> <string>Exo2.0-Bold.otf</string>

View File

@@ -28,42 +28,80 @@
#import <CoreFoundation/CFString.h> #import <CoreFoundation/CFString.h>
#import <objc/runtime.h> #import <objc/runtime.h>
#import <objc/message.h> #import <objc/message.h>
#import <objc/NSObjCRuntime.h>
#import <stdlib.h>
#define trc(format, ...) objc_msgSend( \ #define trc(format, ...) \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ do { \
sel_getUid( "inFile:atLine:trc:" ), \ char *_msg = NULL; \
basename( (char *)__FILE__ ), __LINE__, \ asprintf( &_msg, format, ##__VA_ARGS__ ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
##__VA_ARGS__) _sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
#define dbg(format, ...) objc_msgSend( \ sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
sel_getUid( "inFile:atLine:dbg:" ), \ CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 0, \
basename( (char *)__FILE__ ), __LINE__, \ CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ } while (0)
##__VA_ARGS__)
#define inf(format, ...) objc_msgSend( \ #define dbg(format, ...) \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ do { \
sel_getUid( "inFile:atLine:inf:" ), \ char *_msg = NULL; \
basename( (char *)__FILE__ ), __LINE__, \ asprintf( &_msg, format, ##__VA_ARGS__ ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
##__VA_ARGS__) _sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
#define wrn(format, ...) objc_msgSend( \ sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
sel_getUid( "inFile:atLine:wrn:" ), \ CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 1, \
basename( (char *)__FILE__ ), __LINE__, \ CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ } while (0)
##__VA_ARGS__)
#define err(format, ...) objc_msgSend( \ #define inf(format, ...) \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ do { \
sel_getUid( "inFile:atLine:err:" ), \ char *_msg = NULL; \
basename( (char *)__FILE__ ), __LINE__, \ asprintf( &_msg, format, ##__VA_ARGS__ ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
##__VA_ARGS__) _sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
#define ftl(format, ...) do{objc_msgSend( \ sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
objc_msgSend( (id)objc_getClass("PearlLogger"), sel_getUid( "get" ) ), \ CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
sel_getUid( "inFile:atLine:ftl:" ), \ CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 2, \
basename( (char *)__FILE__ ), __LINE__, \ CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
CFStringCreateWithCString( NULL, format, kCFStringEncodingUTF8 ), \ } while (0)
##__VA_ARGS__); abort(); } while (0)
#define wrn(format, ...) \
do { \
char *_msg = NULL; \
asprintf( &_msg, format, ##__VA_ARGS__ ); \
void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
_sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 3, \
CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
} while (0)
#define err(format, ...) \
do { \
char *_msg = NULL; \
asprintf( &_msg, format, ##__VA_ARGS__ ); \
void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
_sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 4, \
CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
} while (0)
#define ftl(format, ...) \
do { \
char *_msg = NULL; \
asprintf( &_msg, format, ##__VA_ARGS__ ); \
void (*_sendMsg)(id, SEL, CFStringRef, NSInteger, CFStringRef, NSUInteger, CFStringRef) = (void *)objc_msgSend; \
_sendMsg( objc_msgSend( (id)objc_getClass( "PearlLogger" ), sel_getUid( "get" ) ), \
sel_getUid( "inFile:atLine:fromFunction:withLevel:text:" ), \
CFStringCreateWithCString( NULL, basename( (char *)__FILE__ ), kCFStringEncodingUTF8 ), __LINE__, \
CFStringCreateWithCString( NULL, __FUNCTION__, kCFStringEncodingUTF8 ), 5, \
CFStringCreateWithCString( NULL, _msg, kCFStringEncodingUTF8 ) ); \
abort(); \
} while (0)
#endif #endif

View File

@@ -106,8 +106,6 @@
DA2CA4E018D28859007798F8 /* NSTimer+PearlBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = DA2CA4DC18D28859007798F8 /* NSTimer+PearlBlock.h */; }; DA2CA4E018D28859007798F8 /* NSTimer+PearlBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = DA2CA4DC18D28859007798F8 /* NSTimer+PearlBlock.h */; };
DA2CA4E418D28866007798F8 /* NSLayoutConstraint+PearlUIKit.h in Headers */ = {isa = PBXBuildFile; fileRef = DA2CA4E218D28866007798F8 /* NSLayoutConstraint+PearlUIKit.h */; }; DA2CA4E418D28866007798F8 /* NSLayoutConstraint+PearlUIKit.h in Headers */ = {isa = PBXBuildFile; fileRef = DA2CA4E218D28866007798F8 /* NSLayoutConstraint+PearlUIKit.h */; };
DA2CA4E618D2AC10007798F8 /* NSLayoutConstraint+PearlUIKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2CA4E518D2AC10007798F8 /* NSLayoutConstraint+PearlUIKit.m */; }; DA2CA4E618D2AC10007798F8 /* NSLayoutConstraint+PearlUIKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2CA4E518D2AC10007798F8 /* NSLayoutConstraint+PearlUIKit.m */; };
DA30E9CE15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA30E9CB15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h */; };
DA30E9CF15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9CC15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m */; };
DA30E9D015722ECA00A68B4C /* Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9CD15722ECA00A68B4C /* Pearl.m */; }; DA30E9D015722ECA00A68B4C /* Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9CD15722ECA00A68B4C /* Pearl.m */; };
DA30E9D215722EE500A68B4C /* Pearl-Crypto.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */; }; DA30E9D215722EE500A68B4C /* Pearl-Crypto.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */; };
DA30E9D415722EF400A68B4C /* Pearl-UIKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */; }; DA30E9D415722EF400A68B4C /* Pearl-UIKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */; };
@@ -117,7 +115,6 @@
DA32CFF119CF1C8F004F3F0E /* MPStoredSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32CFE819CF1C8F004F3F0E /* MPStoredSiteEntity.m */; }; DA32CFF119CF1C8F004F3F0E /* MPStoredSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32CFE819CF1C8F004F3F0E /* MPStoredSiteEntity.m */; };
DA32CFF319CF1C8F004F3F0E /* MPSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32CFEC19CF1C8F004F3F0E /* MPSiteEntity.m */; }; DA32CFF319CF1C8F004F3F0E /* MPSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32CFEC19CF1C8F004F3F0E /* MPSiteEntity.m */; };
DA32CFF419CF1C8F004F3F0E /* MPGeneratedSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32CFEE19CF1C8F004F3F0E /* MPGeneratedSiteEntity.m */; }; DA32CFF419CF1C8F004F3F0E /* MPGeneratedSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32CFEE19CF1C8F004F3F0E /* MPGeneratedSiteEntity.m */; };
DA32D00819CF4735004F3F0E /* MasterPassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA32D00119CF4735004F3F0E /* MasterPassword.xcdatamodeld */; };
DA32D00919CF5C55004F3F0E /* icon_question.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37FE1711E29600CF925C /* icon_question.png */; }; DA32D00919CF5C55004F3F0E /* icon_question.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37FE1711E29600CF925C /* icon_question.png */; };
DA32D00A19CF5C55004F3F0E /* icon_question@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37FF1711E29600CF925C /* icon_question@2x.png */; }; DA32D00A19CF5C55004F3F0E /* icon_question@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DABD37FF1711E29600CF925C /* icon_question@2x.png */; };
DA32D01A19D046E1004F3F0E /* PearlFixedTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32D01819D046E1004F3F0E /* PearlFixedTableView.m */; }; DA32D01A19D046E1004F3F0E /* PearlFixedTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA32D01819D046E1004F3F0E /* PearlFixedTableView.m */; };
@@ -186,6 +183,9 @@
DA854C8418D4CFBF00106317 /* avatar-add.png in Resources */ = {isa = PBXBuildFile; fileRef = DA854C8218D4CFBF00106317 /* avatar-add.png */; }; DA854C8418D4CFBF00106317 /* avatar-add.png in Resources */ = {isa = PBXBuildFile; fileRef = DA854C8218D4CFBF00106317 /* avatar-add.png */; };
DA92614E1BE1A57500369DE5 /* MPAppDelegate_InApp.m in Sources */ = {isa = PBXBuildFile; fileRef = DA92614D1BE1A57500369DE5 /* MPAppDelegate_InApp.m */; }; DA92614E1BE1A57500369DE5 /* MPAppDelegate_InApp.m in Sources */ = {isa = PBXBuildFile; fileRef = DA92614D1BE1A57500369DE5 /* MPAppDelegate_InApp.m */; };
DA945C8717E3F3FD0053236B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA945C8617E3F3FD0053236B /* Images.xcassets */; }; DA945C8717E3F3FD0053236B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA945C8617E3F3FD0053236B /* Images.xcassets */; };
DA95B50C1C476B6A0067F5EF /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA95B50B1C476B6A0067F5EF /* LocalAuthentication.framework */; };
DA95B50F1C4776F00067F5EF /* NSMutableSet+Pearl.m in Sources */ = {isa = PBXBuildFile; fileRef = DA95B50E1C4776F00067F5EF /* NSMutableSet+Pearl.m */; };
DA95B5191C477DB50067F5EF /* MasterPassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA95B5101C477DB50067F5EF /* MasterPassword.xcdatamodeld */; };
DA95D5F214DF0B2C008D1B94 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */; }; DA95D5F214DF0B2C008D1B94 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */; };
DAA141201922FF020032B392 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA1411C1922FF020032B392 /* PearlTween.m */; }; DAA141201922FF020032B392 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA1411C1922FF020032B392 /* PearlTween.m */; };
DAA141211922FF020032B392 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA1411D1922FF020032B392 /* PearlTween.h */; }; DAA141211922FF020032B392 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA1411D1922FF020032B392 /* PearlTween.h */; };
@@ -599,7 +599,6 @@
DA29992D19C86F5700AF7DF1 /* thumb_generated_login@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "thumb_generated_login@2x.png"; sourceTree = "<group>"; }; DA29992D19C86F5700AF7DF1 /* thumb_generated_login@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "thumb_generated_login@2x.png"; sourceTree = "<group>"; };
DA29992E19C86F5700AF7DF1 /* thumb_generated_login.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = thumb_generated_login.png; sourceTree = "<group>"; }; DA29992E19C86F5700AF7DF1 /* thumb_generated_login.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = thumb_generated_login.png; sourceTree = "<group>"; };
DA29993119C9132F00AF7DF1 /* thumb_generated_login@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "thumb_generated_login@3x.png"; sourceTree = "<group>"; }; DA29993119C9132F00AF7DF1 /* thumb_generated_login@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "thumb_generated_login@3x.png"; sourceTree = "<group>"; };
DA2C3D5E1BD95DEF001137B3 /* libscryptenc-ios-dev.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libscryptenc-ios-dev.a"; sourceTree = "<group>"; };
DA2C3D601BD95EEE001137B3 /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Fabric.framework; path = ../../../External/iOS/Fabric.framework; sourceTree = "<group>"; }; DA2C3D601BD95EEE001137B3 /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Fabric.framework; path = ../../../External/iOS/Fabric.framework; sourceTree = "<group>"; };
DA2C3D621BD96126001137B3 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; DA2C3D621BD96126001137B3 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
DA2C3D641BD9612F001137B3 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; DA2C3D641BD9612F001137B3 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
@@ -609,8 +608,6 @@
DA2CA4DC18D28859007798F8 /* NSTimer+PearlBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTimer+PearlBlock.h"; sourceTree = "<group>"; }; DA2CA4DC18D28859007798F8 /* NSTimer+PearlBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTimer+PearlBlock.h"; sourceTree = "<group>"; };
DA2CA4E218D28866007798F8 /* NSLayoutConstraint+PearlUIKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSLayoutConstraint+PearlUIKit.h"; sourceTree = "<group>"; }; DA2CA4E218D28866007798F8 /* NSLayoutConstraint+PearlUIKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSLayoutConstraint+PearlUIKit.h"; sourceTree = "<group>"; };
DA2CA4E518D2AC10007798F8 /* NSLayoutConstraint+PearlUIKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSLayoutConstraint+PearlUIKit.m"; sourceTree = "<group>"; }; DA2CA4E518D2AC10007798F8 /* NSLayoutConstraint+PearlUIKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSLayoutConstraint+PearlUIKit.m"; sourceTree = "<group>"; };
DA30E9CB15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+PearlMutableInfo.h"; sourceTree = "<group>"; };
DA30E9CC15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+PearlMutableInfo.m"; sourceTree = "<group>"; };
DA30E9CD15722ECA00A68B4C /* Pearl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pearl.m; sourceTree = "<group>"; }; DA30E9CD15722ECA00A68B4C /* Pearl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Pearl.m; sourceTree = "<group>"; };
DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-Crypto.m"; sourceTree = "<group>"; }; DA30E9D115722EE500A68B4C /* Pearl-Crypto.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-Crypto.m"; sourceTree = "<group>"; };
DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-UIKit.m"; sourceTree = "<group>"; }; DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-UIKit.m"; sourceTree = "<group>"; };
@@ -624,12 +621,6 @@
DA32CFED19CF1C8F004F3F0E /* MPSiteEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteEntity.h; sourceTree = "<group>"; }; DA32CFED19CF1C8F004F3F0E /* MPSiteEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteEntity.h; sourceTree = "<group>"; };
DA32CFEE19CF1C8F004F3F0E /* MPGeneratedSiteEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPGeneratedSiteEntity.m; sourceTree = "<group>"; }; DA32CFEE19CF1C8F004F3F0E /* MPGeneratedSiteEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPGeneratedSiteEntity.m; sourceTree = "<group>"; };
DA32CFEF19CF1C8F004F3F0E /* MPGeneratedSiteEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPGeneratedSiteEntity.h; sourceTree = "<group>"; }; DA32CFEF19CF1C8F004F3F0E /* MPGeneratedSiteEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPGeneratedSiteEntity.h; sourceTree = "<group>"; };
DA32D00219CF4735004F3F0E /* MasterPassword 1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 1.xcdatamodel"; sourceTree = "<group>"; };
DA32D00319CF4735004F3F0E /* MasterPassword 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 2.xcdatamodel"; sourceTree = "<group>"; };
DA32D00419CF4735004F3F0E /* MasterPassword 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 3.xcdatamodel"; sourceTree = "<group>"; };
DA32D00519CF4735004F3F0E /* MasterPassword 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 4.xcdatamodel"; sourceTree = "<group>"; };
DA32D00619CF4735004F3F0E /* MasterPassword 5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 5.xcdatamodel"; sourceTree = "<group>"; };
DA32D00719CF4735004F3F0E /* MasterPassword 6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 6.xcdatamodel"; sourceTree = "<group>"; };
DA32D01819D046E1004F3F0E /* PearlFixedTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlFixedTableView.m; sourceTree = "<group>"; }; DA32D01819D046E1004F3F0E /* PearlFixedTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlFixedTableView.m; sourceTree = "<group>"; };
DA32D01919D046E1004F3F0E /* PearlFixedTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlFixedTableView.h; sourceTree = "<group>"; }; DA32D01919D046E1004F3F0E /* PearlFixedTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlFixedTableView.h; sourceTree = "<group>"; };
DA32D02019D111C6004F3F0E /* libKCOrderedAccessorFix.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKCOrderedAccessorFix.a; sourceTree = BUILT_PRODUCTS_DIR; }; DA32D02019D111C6004F3F0E /* libKCOrderedAccessorFix.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKCOrderedAccessorFix.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -673,13 +664,24 @@
DA67460C18DE7F0C00DFE240 /* Exo2.0-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Exo2.0-Bold.otf"; sourceTree = "<group>"; }; DA67460C18DE7F0C00DFE240 /* Exo2.0-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Exo2.0-Bold.otf"; sourceTree = "<group>"; };
DA6774351A4749CC004F356A /* mpw-tests.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-tests.c"; sourceTree = "<group>"; }; DA6774351A4749CC004F356A /* mpw-tests.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-tests.c"; sourceTree = "<group>"; };
DA70EC7F1811B13C00F65DB2 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; DA70EC7F1811B13C00F65DB2 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
DA72BD7719C137D500E6ACFE /* libopensslcrypto-ios-dev.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libopensslcrypto-ios-dev.a"; sourceTree = "<group>"; }; DA7F2C5E1C48B70D00404A26 /* libopensslcrypto-ios-sim.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libopensslcrypto-ios-sim.a"; sourceTree = "<group>"; };
DA8495271A9146E600B3053D /* MasterPassword 7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 7.xcdatamodel"; sourceTree = "<group>"; }; DA7F2C5F1C48B70D00404A26 /* libscryptenc-ios-sim.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libscryptenc-ios-sim.a"; sourceTree = "<group>"; };
DA854C8118D4CFBF00106317 /* avatar-add@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-add@2x.png"; sourceTree = "<group>"; }; DA854C8118D4CFBF00106317 /* avatar-add@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-add@2x.png"; sourceTree = "<group>"; };
DA854C8218D4CFBF00106317 /* avatar-add.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-add.png"; sourceTree = "<group>"; }; DA854C8218D4CFBF00106317 /* avatar-add.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-add.png"; sourceTree = "<group>"; };
DA92614C1BE1A57500369DE5 /* MPAppDelegate_InApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_InApp.h; sourceTree = "<group>"; }; DA92614C1BE1A57500369DE5 /* MPAppDelegate_InApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_InApp.h; sourceTree = "<group>"; };
DA92614D1BE1A57500369DE5 /* MPAppDelegate_InApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_InApp.m; sourceTree = "<group>"; }; DA92614D1BE1A57500369DE5 /* MPAppDelegate_InApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_InApp.m; sourceTree = "<group>"; };
DA945C8617E3F3FD0053236B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; DA945C8617E3F3FD0053236B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
DA95B50B1C476B6A0067F5EF /* LocalAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthentication.framework; path = System/Library/Frameworks/LocalAuthentication.framework; sourceTree = SDKROOT; };
DA95B50D1C4776F00067F5EF /* NSMutableSet+Pearl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableSet+Pearl.h"; sourceTree = "<group>"; };
DA95B50E1C4776F00067F5EF /* NSMutableSet+Pearl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableSet+Pearl.m"; sourceTree = "<group>"; };
DA95B5111C477DB50067F5EF /* MasterPassword 1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 1.xcdatamodel"; sourceTree = "<group>"; };
DA95B5121C477DB50067F5EF /* MasterPassword 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 2.xcdatamodel"; sourceTree = "<group>"; };
DA95B5131C477DB50067F5EF /* MasterPassword 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 3.xcdatamodel"; sourceTree = "<group>"; };
DA95B5141C477DB50067F5EF /* MasterPassword 4.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 4.xcdatamodel"; sourceTree = "<group>"; };
DA95B5151C477DB50067F5EF /* MasterPassword 5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 5.xcdatamodel"; sourceTree = "<group>"; };
DA95B5161C477DB50067F5EF /* MasterPassword 6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 6.xcdatamodel"; sourceTree = "<group>"; };
DA95B5171C477DB50067F5EF /* MasterPassword 7.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 7.xcdatamodel"; sourceTree = "<group>"; };
DA95B5181C477DB50067F5EF /* MasterPassword 8.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 8.xcdatamodel"; sourceTree = "<group>"; };
DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
DAA141191922FED80032B392 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; }; DAA141191922FED80032B392 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; };
DAA1411C1922FF020032B392 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; }; DAA1411C1922FF020032B392 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; };
@@ -1551,6 +1553,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
DA95B50C1C476B6A0067F5EF /* LocalAuthentication.framework in Frameworks */,
DA2C3D651BD9612F001137B3 /* libz.tbd in Frameworks */, DA2C3D651BD9612F001137B3 /* libz.tbd in Frameworks */,
DA2C3D631BD96126001137B3 /* libc++.tbd in Frameworks */, DA2C3D631BD96126001137B3 /* libc++.tbd in Frameworks */,
DAA1761B19D86D0D0044227B /* libAttributedMarkdown.a in Frameworks */, DAA1761B19D86D0D0044227B /* libAttributedMarkdown.a in Frameworks */,
@@ -1764,6 +1767,7 @@
DA5BFA47147E415C00F98B1E /* Frameworks */ = { DA5BFA47147E415C00F98B1E /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DA95B50B1C476B6A0067F5EF /* LocalAuthentication.framework */,
DA2C3D641BD9612F001137B3 /* libz.tbd */, DA2C3D641BD9612F001137B3 /* libz.tbd */,
DA2C3D621BD96126001137B3 /* libc++.tbd */, DA2C3D621BD96126001137B3 /* libc++.tbd */,
DA2C3D601BD95EEE001137B3 /* Fabric.framework */, DA2C3D601BD95EEE001137B3 /* Fabric.framework */,
@@ -1791,9 +1795,9 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DA5E5C6417248959003798D8 /* include */, DA5E5C6417248959003798D8 /* include */,
DA72BD7719C137D500E6ACFE /* libopensslcrypto-ios-dev.a */, DA7F2C5E1C48B70D00404A26 /* libopensslcrypto-ios-sim.a */,
DAE8E65119867AB500416A0F /* libopensslcrypto-ios.a */, DAE8E65119867AB500416A0F /* libopensslcrypto-ios.a */,
DA2C3D5E1BD95DEF001137B3 /* libscryptenc-ios-dev.a */, DA7F2C5F1C48B70D00404A26 /* libscryptenc-ios-sim.a */,
DAFFC63E17EDDA7C007BB020 /* libscryptenc-ios.a */, DAFFC63E17EDDA7C007BB020 /* libscryptenc-ios.a */,
); );
path = lib; path = lib;
@@ -2559,7 +2563,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DABD3BD71711E2DC00CF925C /* iOS */, DABD3BD71711E2DC00CF925C /* iOS */,
DA32D00119CF4735004F3F0E /* MasterPassword.xcdatamodeld */, DA95B5101C477DB50067F5EF /* MasterPassword.xcdatamodeld */,
DABD3BA01711E2DC00CF925C /* MPAlgorithm.h */, DABD3BA01711E2DC00CF925C /* MPAlgorithm.h */,
DABD3BA11711E2DC00CF925C /* MPAlgorithm.m */, DABD3BA11711E2DC00CF925C /* MPAlgorithm.m */,
DABD3BA21711E2DC00CF925C /* MPAlgorithmV0.h */, DABD3BA21711E2DC00CF925C /* MPAlgorithmV0.h */,
@@ -2808,35 +2812,34 @@
DAFE45D715039823003ABA7C /* Pearl */ = { DAFE45D715039823003ABA7C /* Pearl */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DACE2F6319BA6A0A0010F92E /* PearlProfiler.m */,
DACE2F6419BA6A0A0010F92E /* PearlProfiler.h */,
DAA1411C1922FF020032B392 /* PearlTween.m */,
DAA1411D1922FF020032B392 /* PearlTween.h */,
DAA1411E1922FF020032B392 /* include */, DAA1411E1922FF020032B392 /* include */,
DAF4EF4E190A81E400023C90 /* NSManagedObject+Pearl.m */,
DAF4EF4F190A81E400023C90 /* NSManagedObject+Pearl.h */,
DA2CA4D918D28859007798F8 /* NSArray+Pearl.m */,
DA2CA4DA18D28859007798F8 /* NSArray+Pearl.h */,
DA2CA4DB18D28859007798F8 /* NSTimer+PearlBlock.m */,
DA2CA4DC18D28859007798F8 /* NSTimer+PearlBlock.h */,
DA3509FC15F101A500C14A8E /* PearlQueue.h */,
DA3509FD15F101A500C14A8E /* PearlQueue.m */,
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */,
93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */,
93D396D04E57792A54D437AC /* NSArray+Indexing.h */, 93D396D04E57792A54D437AC /* NSArray+Indexing.h */,
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */, 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */,
DA2CA4DA18D28859007798F8 /* NSArray+Pearl.h */,
DA2CA4D918D28859007798F8 /* NSArray+Pearl.m */,
DAFE4A63150399FF003ABA93 /* NSDateFormatter+RFC3339.h */, DAFE4A63150399FF003ABA93 /* NSDateFormatter+RFC3339.h */,
DAFE4A63150399FF003ABA91 /* NSDateFormatter+RFC3339.m */, DAFE4A63150399FF003ABA91 /* NSDateFormatter+RFC3339.m */,
DAFE4A63150399FF003ABA87 /* NSObject+PearlKVO.h */, 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */,
DAFE4A63150399FF003ABA85 /* NSObject+PearlKVO.m */, 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */,
DA30E9CB15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h */, 93D398C95847261903D781D3 /* NSError+PearlFullDescription.h */,
DA30E9CC15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m */, 93D39F9106F2CCFB94283188 /* NSError+PearlFullDescription.m */,
DAF4EF4F190A81E400023C90 /* NSManagedObject+Pearl.h */,
DAF4EF4E190A81E400023C90 /* NSManagedObject+Pearl.m */,
DA95B50D1C4776F00067F5EF /* NSMutableSet+Pearl.h */,
DA95B50E1C4776F00067F5EF /* NSMutableSet+Pearl.m */,
93D391AA32F24290C424438E /* NSNotificationCenter+PearlEasyCleanup.h */,
DAFE45D815039823003ABA7C /* NSObject+PearlExport.h */, DAFE45D815039823003ABA7C /* NSObject+PearlExport.h */,
DAFE45D915039823003ABA7C /* NSObject+PearlExport.m */, DAFE45D915039823003ABA7C /* NSObject+PearlExport.m */,
DAFE4A63150399FF003ABA87 /* NSObject+PearlKVO.h */,
DAFE4A63150399FF003ABA85 /* NSObject+PearlKVO.m */,
93D397F4BAFFF7CF3F1B21A4 /* NSPersistentStore+PearlMigration.h */,
93D399C2F3D48E57C4803BDC /* NSPersistentStore+PearlMigration.m */,
DAFE45DA15039823003ABA7C /* NSString+PearlNSArrayFormat.h */, DAFE45DA15039823003ABA7C /* NSString+PearlNSArrayFormat.h */,
DAFE45DB15039823003ABA7C /* NSString+PearlNSArrayFormat.m */, DAFE45DB15039823003ABA7C /* NSString+PearlNSArrayFormat.m */,
DAFE45DC15039823003ABA7C /* NSString+PearlSEL.h */, DAFE45DC15039823003ABA7C /* NSString+PearlSEL.h */,
DAFE45DD15039823003ABA7C /* NSString+PearlSEL.m */, DAFE45DD15039823003ABA7C /* NSString+PearlSEL.m */,
DA2CA4DC18D28859007798F8 /* NSTimer+PearlBlock.h */,
DA2CA4DB18D28859007798F8 /* NSTimer+PearlBlock.m */,
DAFE45DE15039823003ABA7C /* Pearl.h */, DAFE45DE15039823003ABA7C /* Pearl.h */,
DA30E9CD15722ECA00A68B4C /* Pearl.m */, DA30E9CD15722ECA00A68B4C /* Pearl.m */,
DAFE45DF15039823003ABA7C /* PearlAbstractStrings.h */, DAFE45DF15039823003ABA7C /* PearlAbstractStrings.h */,
@@ -2857,18 +2860,19 @@
DAFE45EE15039823003ABA7C /* PearlMathUtils.m */, DAFE45EE15039823003ABA7C /* PearlMathUtils.m */,
DAFE45EF15039823003ABA7C /* PearlObjectUtils.h */, DAFE45EF15039823003ABA7C /* PearlObjectUtils.h */,
DAFE45F015039823003ABA7C /* PearlObjectUtils.m */, DAFE45F015039823003ABA7C /* PearlObjectUtils.m */,
DACE2F6419BA6A0A0010F92E /* PearlProfiler.h */,
DACE2F6319BA6A0A0010F92E /* PearlProfiler.m */,
DA3509FC15F101A500C14A8E /* PearlQueue.h */,
DA3509FD15F101A500C14A8E /* PearlQueue.m */,
DAFE45F115039823003ABA7C /* PearlResettable.h */, DAFE45F115039823003ABA7C /* PearlResettable.h */,
DAFE45F215039823003ABA7C /* PearlStrings.h */, DAFE45F215039823003ABA7C /* PearlStrings.h */,
DAFE45F315039823003ABA7C /* PearlStrings.m */, DAFE45F315039823003ABA7C /* PearlStrings.m */,
DAFE45F415039823003ABA7C /* PearlStringUtils.h */, DAFE45F415039823003ABA7C /* PearlStringUtils.h */,
DAFE45F515039823003ABA7C /* PearlStringUtils.m */, DAFE45F515039823003ABA7C /* PearlStringUtils.m */,
DAA1411D1922FF020032B392 /* PearlTween.h */,
DAA1411C1922FF020032B392 /* PearlTween.m */,
DAFE45F815039823003ABA7C /* README */, DAFE45F815039823003ABA7C /* README */,
DAFE45F915039823003ABA7C /* Resources */, DAFE45F915039823003ABA7C /* Resources */,
93D39F9106F2CCFB94283188 /* NSError+PearlFullDescription.m */,
93D398C95847261903D781D3 /* NSError+PearlFullDescription.h */,
93D391AA32F24290C424438E /* NSNotificationCenter+PearlEasyCleanup.h */,
93D399C2F3D48E57C4803BDC /* NSPersistentStore+PearlMigration.m */,
93D397F4BAFFF7CF3F1B21A4 /* NSPersistentStore+PearlMigration.h */,
); );
path = Pearl; path = Pearl;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -2903,45 +2907,23 @@
DAFE460715039823003ABA7C /* Pearl-UIKit */ = { DAFE460715039823003ABA7C /* Pearl-UIKit */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DA32D01819D046E1004F3F0E /* PearlFixedTableView.m */,
DA32D01919D046E1004F3F0E /* PearlFixedTableView.h */,
DAE2726119CE9CB3007C5262 /* UITableViewCell+PearlDeque.m */,
DAE2726219CE9CB3007C5262 /* UITableViewCell+PearlDeque.h */,
DAEFB01C19BCBD9E00525079 /* UIView+LayoutGone.m */,
DAEFB01D19BCBD9E00525079 /* UIView+LayoutGone.h */,
DACE2F6719BA6A2A0010F92E /* UIView+FontScale.m */,
DACE2F6819BA6A2A0010F92E /* PearlMutableStaticTableViewController.m */,
DACE2F6919BA6A2A0010F92E /* PearlMutableStaticTableViewController.h */,
DACE2F6A19BA6A2A0010F92E /* UIView+FontScale.h */,
DA250A13195665A100AC23F1 /* UITableView+PearlReloadFromArray.m */,
DA250A14195665A100AC23F1 /* UITableView+PearlReloadFromArray.h */,
DA250A15195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.m */,
DA250A16195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.h */,
DAEC85B118E3DD9A007FC0DF /* UIView+Touches.m */,
DAEC85B218E3DD9A007FC0DF /* PearlUINavigationBar.m */,
DAEC85B318E3DD9A007FC0DF /* PearlUINavigationBar.h */,
DAEC85B418E3DD9A007FC0DF /* UIView+Touches.h */,
DA2CA4E518D2AC10007798F8 /* NSLayoutConstraint+PearlUIKit.m */,
DA2CA4E218D28866007798F8 /* NSLayoutConstraint+PearlUIKit.h */, DA2CA4E218D28866007798F8 /* NSLayoutConstraint+PearlUIKit.h */,
93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */, DA2CA4E518D2AC10007798F8 /* NSLayoutConstraint+PearlUIKit.m */,
93D393BB973253D4BAAC84AA /* PearlEMail.m */,
DAFE4A63150399FF003ABA8F /* UIScrollView+PearlFlashingIndicators.h */,
DAFE4A63150399FF003ABA8D /* UIScrollView+PearlFlashingIndicators.m */,
DAFE4A63150399FF003ABA8B /* UIControl+PearlSelect.h */,
DAFE4A63150399FF003ABA89 /* UIControl+PearlSelect.m */,
DAFE4A63150399FF003ABA83 /* UIControl+PearlBlocks.h */,
DAFE4A63150399FF003ABA81 /* UIControl+PearlBlocks.m */,
DAFE460815039823003ABA7C /* Pearl-UIKit-Dependencies.h */, DAFE460815039823003ABA7C /* Pearl-UIKit-Dependencies.h */,
DAFE460915039823003ABA7C /* Pearl-UIKit.h */, DAFE460915039823003ABA7C /* Pearl-UIKit.h */,
DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */, DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */,
DAFE460A15039823003ABA7C /* PearlAlert.h */, DAFE460A15039823003ABA7C /* PearlAlert.h */,
DAFE460B15039823003ABA7C /* PearlAlert.m */, DAFE460B15039823003ABA7C /* PearlAlert.m */,
DAFE4A60150399FF003ABA7C /* PearlAppDelegate.m */,
DAFE4A61150399FF003ABA7C /* PearlAppDelegate.h */, DAFE4A61150399FF003ABA7C /* PearlAppDelegate.h */,
DAFE4A60150399FF003ABA7C /* PearlAppDelegate.m */,
DAFE460C15039823003ABA7C /* PearlArrayTVC.h */, DAFE460C15039823003ABA7C /* PearlArrayTVC.h */,
DAFE460D15039823003ABA7C /* PearlArrayTVC.m */, DAFE460D15039823003ABA7C /* PearlArrayTVC.m */,
DAFE460E15039823003ABA7C /* PearlBoxView.h */, DAFE460E15039823003ABA7C /* PearlBoxView.h */,
DAFE460F15039823003ABA7C /* PearlBoxView.m */, DAFE460F15039823003ABA7C /* PearlBoxView.m */,
93D39F7C9F47BF6387FBC5C3 /* PearlEMail.h */,
93D393BB973253D4BAAC84AA /* PearlEMail.m */,
DA32D01919D046E1004F3F0E /* PearlFixedTableView.h */,
DA32D01819D046E1004F3F0E /* PearlFixedTableView.m */,
DAFE461015039823003ABA7C /* PearlGradientView.h */, DAFE461015039823003ABA7C /* PearlGradientView.h */,
DAFE461115039823003ABA7C /* PearlGradientView.m */, DAFE461115039823003ABA7C /* PearlGradientView.m */,
DAFE461215039823003ABA7C /* PearlLayout.h */, DAFE461215039823003ABA7C /* PearlLayout.h */,
@@ -2950,12 +2932,24 @@
DAFE461515039823003ABA7C /* PearlLayoutView.m */, DAFE461515039823003ABA7C /* PearlLayoutView.m */,
DAFE461615039823003ABA7C /* PearlMessageView.h */, DAFE461615039823003ABA7C /* PearlMessageView.h */,
DAFE461715039823003ABA7C /* PearlMessageView.m */, DAFE461715039823003ABA7C /* PearlMessageView.m */,
DACE2F6919BA6A2A0010F92E /* PearlMutableStaticTableViewController.h */,
DACE2F6819BA6A2A0010F92E /* PearlMutableStaticTableViewController.m */,
93D398567FD02DB2647B8CF3 /* PearlNavigationController.h */,
93D3956915634581E737B38C /* PearlNavigationController.m */,
93D3942A356B639724157982 /* PearlOverlay.h */,
93D390FADEB325D8D54A957D /* PearlOverlay.m */,
DAFE461815039823003ABA7C /* PearlRootViewController.h */, DAFE461815039823003ABA7C /* PearlRootViewController.h */,
DAFE461915039823003ABA7C /* PearlRootViewController.m */, DAFE461915039823003ABA7C /* PearlRootViewController.m */,
DAFE461A15039823003ABA7C /* PearlSheet.h */, DAFE461A15039823003ABA7C /* PearlSheet.h */,
DAFE461B15039823003ABA7C /* PearlSheet.m */, DAFE461B15039823003ABA7C /* PearlSheet.m */,
93D39A4759186F6D2D34AA6B /* PearlSizedTextView.h */,
93D39156E806BB78E04F78B9 /* PearlSizedTextView.m */,
93D39B1D8177A86C5B9EDDE3 /* PearlUICollectionView.h */,
93D39D8A953779B35403AF6E /* PearlUICollectionView.m */,
DAFE461C15039823003ABA7C /* PearlUIDebug.h */, DAFE461C15039823003ABA7C /* PearlUIDebug.h */,
DAFE461D15039823003ABA7C /* PearlUIDebug.m */, DAFE461D15039823003ABA7C /* PearlUIDebug.m */,
DAEC85B318E3DD9A007FC0DF /* PearlUINavigationBar.h */,
DAEC85B218E3DD9A007FC0DF /* PearlUINavigationBar.m */,
DAFE461E15039823003ABA7C /* PearlUIUtils.h */, DAFE461E15039823003ABA7C /* PearlUIUtils.h */,
DAFE461F15039823003ABA7C /* PearlUIUtils.m */, DAFE461F15039823003ABA7C /* PearlUIUtils.m */,
DAFE462015039823003ABA7C /* PearlValidatingTextField.h */, DAFE462015039823003ABA7C /* PearlValidatingTextField.h */,
@@ -2964,24 +2958,34 @@
DAFE462315039823003ABA7C /* PearlWebViewController.m */, DAFE462315039823003ABA7C /* PearlWebViewController.m */,
DAFE462415039823003ABA7C /* README */, DAFE462415039823003ABA7C /* README */,
DAFE462515039823003ABA7C /* Resources */, DAFE462515039823003ABA7C /* Resources */,
DA250A16195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.h */,
DA250A15195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.m */,
93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadFromArray.h */,
93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */,
DAFE4A63150399FF003ABA83 /* UIControl+PearlBlocks.h */,
DAFE4A63150399FF003ABA81 /* UIControl+PearlBlocks.m */,
DAFE4A63150399FF003ABA8B /* UIControl+PearlSelect.h */,
DAFE4A63150399FF003ABA89 /* UIControl+PearlSelect.m */,
DAFE4A1115039824003ABA7C /* UIImage+PearlScaling.h */, DAFE4A1115039824003ABA7C /* UIImage+PearlScaling.h */,
DAFE4A1215039824003ABA7C /* UIImage+PearlScaling.m */, DAFE4A1215039824003ABA7C /* UIImage+PearlScaling.m */,
93D390FADEB325D8D54A957D /* PearlOverlay.m */,
93D3942A356B639724157982 /* PearlOverlay.h */,
93D3956915634581E737B38C /* PearlNavigationController.m */,
93D398567FD02DB2647B8CF3 /* PearlNavigationController.h */,
93D390FB3110DCCE68E600DC /* UIScrollView+PearlAdjustInsets.m */,
93D39DE2CB351D4E3789462B /* UIScrollView+PearlAdjustInsets.h */,
93D39D8A953779B35403AF6E /* PearlUICollectionView.m */,
93D39B1D8177A86C5B9EDDE3 /* PearlUICollectionView.h */,
93D39A1DDFA09AE2E14D26DC /* UIResponder+PearlFirstResponder.m */,
93D394482BB07F90E8FD1314 /* UIResponder+PearlFirstResponder.h */, 93D394482BB07F90E8FD1314 /* UIResponder+PearlFirstResponder.h */,
93D39156E806BB78E04F78B9 /* PearlSizedTextView.m */, 93D39A1DDFA09AE2E14D26DC /* UIResponder+PearlFirstResponder.m */,
93D39A4759186F6D2D34AA6B /* PearlSizedTextView.h */, 93D39DE2CB351D4E3789462B /* UIScrollView+PearlAdjustInsets.h */,
93D3977321EB249981821AB0 /* UITextView+PearlAttributes.m */, 93D390FB3110DCCE68E600DC /* UIScrollView+PearlAdjustInsets.m */,
DAFE4A63150399FF003ABA8F /* UIScrollView+PearlFlashingIndicators.h */,
DAFE4A63150399FF003ABA8D /* UIScrollView+PearlFlashingIndicators.m */,
DA250A14195665A100AC23F1 /* UITableView+PearlReloadFromArray.h */,
DA250A13195665A100AC23F1 /* UITableView+PearlReloadFromArray.m */,
DAE2726219CE9CB3007C5262 /* UITableViewCell+PearlDeque.h */,
DAE2726119CE9CB3007C5262 /* UITableViewCell+PearlDeque.m */,
93D39AA10CD00D05937671B1 /* UITextView+PearlAttributes.h */, 93D39AA10CD00D05937671B1 /* UITextView+PearlAttributes.h */,
93D3908DF8EABBD952065DC0 /* UICollectionView+PearlReloadFromArray.m */, 93D3977321EB249981821AB0 /* UITextView+PearlAttributes.m */,
93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadFromArray.h */, DACE2F6A19BA6A2A0010F92E /* UIView+FontScale.h */,
DACE2F6719BA6A2A0010F92E /* UIView+FontScale.m */,
DAEFB01D19BCBD9E00525079 /* UIView+LayoutGone.h */,
DAEFB01C19BCBD9E00525079 /* UIView+LayoutGone.m */,
DAEC85B418E3DD9A007FC0DF /* UIView+Touches.h */,
DAEC85B118E3DD9A007FC0DF /* UIView+Touches.m */,
); );
path = "Pearl-UIKit"; path = "Pearl-UIKit";
sourceTree = "<group>"; sourceTree = "<group>";
@@ -3067,7 +3071,6 @@
DAFE4A5615039824003ABA7C /* PearlWebViewController.h in Headers */, DAFE4A5615039824003ABA7C /* PearlWebViewController.h in Headers */,
DAFE4A5815039824003ABA7C /* UIImage+PearlScaling.h in Headers */, DAFE4A5815039824003ABA7C /* UIImage+PearlScaling.h in Headers */,
DAFE4A63150399FF003ABA7C /* PearlAppDelegate.h in Headers */, DAFE4A63150399FF003ABA7C /* PearlAppDelegate.h in Headers */,
DA30E9CE15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h in Headers */,
DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */, DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */,
DAA141211922FF020032B392 /* PearlTween.h in Headers */, DAA141211922FF020032B392 /* PearlTween.h in Headers */,
DAFE4A63150399FF003ABA84 /* UIControl+PearlBlocks.h in Headers */, DAFE4A63150399FF003ABA84 /* UIControl+PearlBlocks.h in Headers */,
@@ -3646,12 +3649,13 @@
93D39392DEDA376F93C6C718 /* MPCell.m in Sources */, 93D39392DEDA376F93C6C718 /* MPCell.m in Sources */,
93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */, 93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */,
93D398ECD7D1A0DEDDADF516 /* MPEmergencyViewController.m in Sources */, 93D398ECD7D1A0DEDDADF516 /* MPEmergencyViewController.m in Sources */,
DA32D00819CF4735004F3F0E /* MasterPassword.xcdatamodeld in Sources */, DA95B50F1C4776F00067F5EF /* NSMutableSet+Pearl.m in Sources */,
93D394B5036C882B33C71872 /* MPPasswordsSegue.m in Sources */, 93D394B5036C882B33C71872 /* MPPasswordsSegue.m in Sources */,
93D39673DDC085BE72C34D7C /* MPPopdownSegue.m in Sources */, 93D39673DDC085BE72C34D7C /* MPPopdownSegue.m in Sources */,
93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */, 93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */,
93D396D8B67DA6522CDBA142 /* MPCoachmarkViewController.m in Sources */, 93D396D8B67DA6522CDBA142 /* MPCoachmarkViewController.m in Sources */,
DAADBFE01A68763B00F7A756 /* mpw-algorithm.c in Sources */, DAADBFE01A68763B00F7A756 /* mpw-algorithm.c in Sources */,
DA95B5191C477DB50067F5EF /* MasterPassword.xcdatamodeld in Sources */,
93D39EAA4D064193074D3021 /* MPFixable.m in Sources */, 93D39EAA4D064193074D3021 /* MPFixable.m in Sources */,
DA32CFF119CF1C8F004F3F0E /* MPStoredSiteEntity.m in Sources */, DA32CFF119CF1C8F004F3F0E /* MPStoredSiteEntity.m in Sources */,
93D394982CBD25D46692DD7C /* MPWebViewController.m in Sources */, 93D394982CBD25D46692DD7C /* MPWebViewController.m in Sources */,
@@ -3743,7 +3747,6 @@
DACE2F6C19BA6A2A0010F92E /* PearlMutableStaticTableViewController.m in Sources */, DACE2F6C19BA6A2A0010F92E /* PearlMutableStaticTableViewController.m in Sources */,
DAFE4A5915039824003ABA7C /* UIImage+PearlScaling.m in Sources */, DAFE4A5915039824003ABA7C /* UIImage+PearlScaling.m in Sources */,
DAFE4A62150399FF003ABA7C /* PearlAppDelegate.m in Sources */, DAFE4A62150399FF003ABA7C /* PearlAppDelegate.m in Sources */,
DA30E9CF15722ECA00A68B4C /* NSBundle+PearlMutableInfo.m in Sources */,
DA30E9D015722ECA00A68B4C /* Pearl.m in Sources */, DA30E9D015722ECA00A68B4C /* Pearl.m in Sources */,
DA30E9D215722EE500A68B4C /* Pearl-Crypto.m in Sources */, DA30E9D215722EE500A68B4C /* Pearl-Crypto.m in Sources */,
DA30E9D415722EF400A68B4C /* Pearl-UIKit.m in Sources */, DA30E9D415722EF400A68B4C /* Pearl-UIKit.m in Sources */,
@@ -4019,6 +4022,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Maarten Billemont (DWGU95U4ZD)";
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"\"$(SRCROOT)/../../../External/iOS\"", "\"$(SRCROOT)/../../../External/iOS\"",
@@ -4042,12 +4046,10 @@
); );
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( "OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"$(inherited)", "$(inherited)",
"-lscryptenc-ios-dev", "-lscryptenc-ios-sim",
"-lopensslcrypto-ios-dev", "-lopensslcrypto-ios-sim",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.lyndir.lhunath.MasterPassword; PRODUCT_BUNDLE_IDENTIFIER = com.lyndir.lhunath.MasterPassword;
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "3251b7d3-04df-4c8e-a410-d020ffc92d10";
SKIP_INSTALL = NO; SKIP_INSTALL = NO;
TARGETED_DEVICE_FAMILY = 1; TARGETED_DEVICE_FAMILY = 1;
}; };
@@ -4059,6 +4061,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Maarten Billemont (HL3Q45LX9N)";
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
EXCLUDED_SOURCE_FILE_NAMES = libDCIntrospect.a; EXCLUDED_SOURCE_FILE_NAMES = libDCIntrospect.a;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@@ -4080,12 +4083,10 @@
); );
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( "OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"$(inherited)", "$(inherited)",
"-lscryptenc-ios-dev", "-lscryptenc-ios-sim",
"-lopensslcrypto-ios-dev", "-lopensslcrypto-ios-sim",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.lyndir.lhunath.MasterPassword; PRODUCT_BUNDLE_IDENTIFIER = com.lyndir.lhunath.MasterPassword;
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "59b587d0-3ef3-4691-9f12-c48f7f283002";
SKIP_INSTALL = NO; SKIP_INSTALL = NO;
STRIP_INSTALLED_PRODUCT = YES; STRIP_INSTALLED_PRODUCT = YES;
TARGETED_DEVICE_FAMILY = 1; TARGETED_DEVICE_FAMILY = 1;
@@ -4183,6 +4184,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Maarten Billemont (HL3Q45LX9N)";
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
EXCLUDED_SOURCE_FILE_NAMES = libDCIntrospect.a; EXCLUDED_SOURCE_FILE_NAMES = libDCIntrospect.a;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@@ -4204,12 +4206,10 @@
); );
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( "OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"$(inherited)", "$(inherited)",
"-lscryptenc-ios-dev", "-lscryptenc-ios-sim",
"-lopensslcrypto-ios-dev", "-lopensslcrypto-ios-sim",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.lyndir.lhunath.MasterPassword; PRODUCT_BUNDLE_IDENTIFIER = com.lyndir.lhunath.MasterPassword;
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "a1d8cfc8-b8db-4544-af34-28cc75e46c40";
SKIP_INSTALL = NO; SKIP_INSTALL = NO;
STRIP_INSTALLED_PRODUCT = YES; STRIP_INSTALLED_PRODUCT = YES;
TARGETED_DEVICE_FAMILY = 1; TARGETED_DEVICE_FAMILY = 1;
@@ -4458,18 +4458,19 @@
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCVersionGroup section */ /* Begin XCVersionGroup section */
DA32D00119CF4735004F3F0E /* MasterPassword.xcdatamodeld */ = { DA95B5101C477DB50067F5EF /* MasterPassword.xcdatamodeld */ = {
isa = XCVersionGroup; isa = XCVersionGroup;
children = ( children = (
DA8495271A9146E600B3053D /* MasterPassword 7.xcdatamodel */, DA95B5111C477DB50067F5EF /* MasterPassword 1.xcdatamodel */,
DA32D00219CF4735004F3F0E /* MasterPassword 1.xcdatamodel */, DA95B5121C477DB50067F5EF /* MasterPassword 2.xcdatamodel */,
DA32D00319CF4735004F3F0E /* MasterPassword 2.xcdatamodel */, DA95B5131C477DB50067F5EF /* MasterPassword 3.xcdatamodel */,
DA32D00419CF4735004F3F0E /* MasterPassword 3.xcdatamodel */, DA95B5141C477DB50067F5EF /* MasterPassword 4.xcdatamodel */,
DA32D00519CF4735004F3F0E /* MasterPassword 4.xcdatamodel */, DA95B5151C477DB50067F5EF /* MasterPassword 5.xcdatamodel */,
DA32D00619CF4735004F3F0E /* MasterPassword 5.xcdatamodel */, DA95B5161C477DB50067F5EF /* MasterPassword 6.xcdatamodel */,
DA32D00719CF4735004F3F0E /* MasterPassword 6.xcdatamodel */, DA95B5171C477DB50067F5EF /* MasterPassword 7.xcdatamodel */,
DA95B5181C477DB50067F5EF /* MasterPassword 8.xcdatamodel */,
); );
currentVersion = DA8495271A9146E600B3053D /* MasterPassword 7.xcdatamodel */; currentVersion = DA95B5181C477DB50067F5EF /* MasterPassword 8.xcdatamodel */;
path = MasterPassword.xcdatamodeld; path = MasterPassword.xcdatamodeld;
sourceTree = "<group>"; sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel; versionGroupType = wrapper.xcdatamodel;

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 585 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 KiB

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 764 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Some files were not shown because too many files have changed in this diff Show More