2
0

Compare commits

..

67 Commits

Author SHA1 Message Date
Maarten Billemont
1f173d7586 Support for dark mode icon. 2014-10-30 21:05:13 -04:00
Maarten Billemont
34be1eac70 Mac LoginHelper distribution configuration. 2014-10-30 00:39:56 -04:00
Maarten Billemont
e1a9c8194c Bump xib. 2014-10-30 00:26:42 -04:00
Maarten Billemont
e18dee2242 Also try upgrading to V2 if migrationlevel is unset but a store is available. 2014-10-30 00:18:01 -04:00
Maarten Billemont
a38829c1e2 Match the define name to its value. 2014-10-29 21:55:18 -04:00
Maarten Billemont
8615f6af5d Fuzzy site name search and highlight fuzzy results. 2014-10-29 21:24:35 -04:00
Maarten Billemont
d642cb1aee Use exposure adjust for darkening without destroying dark backgrounds. 2014-10-28 17:20:38 -04:00
Maarten Billemont
2be2a19fa0 Build fixes and layout improvements for Mac on Yosemite. 2014-10-28 00:53:16 -04:00
Maarten Billemont
0d5b51ed8d Put Mac icon into AppIconSet 2014-10-26 13:26:41 -04:00
Maarten Billemont
c781bcf10a Move Info.plist update script into Scripts to share it between Mac and iOS. 2014-10-26 12:01:30 -04:00
Maarten Billemont
1c45a0df4a Don't crash if attempting to import with an invalid password type. 2014-10-26 10:54:28 -04:00
Maarten Billemont
6b16e4d606 Remove USM from Mac app. 2014-10-26 10:41:15 -04:00
Maarten Billemont
e837752777 Explicitly synchronize configuration updates and warn if it fails. 2014-10-24 00:35:05 -04:00
Maarten Billemont
84c23fa7f6 debug genassets. 2014-10-24 00:00:51 -04:00
Maarten Billemont
2b0cc8ec7b Reference mpw-js from the main page + interlace the images. 2014-10-23 22:17:17 -04:00
Maarten Billemont
6f77e1922b Remove adwords. 2014-10-23 21:57:03 -04:00
Maarten Billemont
653f90c59c Force a refresh of the referenced stylesheet and js. 2014-10-23 21:35:17 -04:00
Maarten Billemont
3076cc3de4 A few disclaimers on mpw-js. 2014-10-23 21:33:19 -04:00
Maarten Billemont
15c53c06c6 Merge branch 'master' of github.com:Lyndir/MasterPassword 2014-10-23 20:10:44 -04:00
Maarten Billemont
b3a886a6db mpw-js: A javascript implementation of Master Password. 2014-10-23 20:10:25 -04:00
Maarten Billemont
41ae6a5de5 Remove pushqueue/popqueue, not compatible with bash3 2014-10-23 17:29:14 -04:00
Maarten Billemont
92bd2cd016 Explicitly use sha256 digests. 2014-10-23 12:03:19 -04:00
Maarten Billemont
4b975b5b04 Fix pkg_sha of crypt_blowfish; verified by checking the signature of the package against crypt_blowfish-1.3.tar.gz.sign 2014-10-23 00:26:07 -04:00
Maarten Billemont
56f04a8924 xctool gets project targets confused; specify iOS project explicitly. 2014-10-23 00:14:45 -04:00
Maarten Billemont
3c2b5de4b8 Fix crash when clearing the pasteboard. 2014-10-22 23:32:25 -04:00
Maarten Billemont
33e1492b44 clean up todo. 2014-10-22 23:21:21 -04:00
Maarten Billemont
9384e27247 submodules needs to be explicitly true? + fix version numbering. 2014-10-22 23:10:07 -04:00
Maarten Billemont
a95561dd50 Re-enable submodule support in Travis; Pearl is no longer excessive. 2014-10-22 23:05:04 -04:00
Maarten Billemont
9d809f34d9 Remove MPCheckpoints, no longer useful. Perform pasteboard importing on a background thread. 2014-10-22 23:00:20 -04:00
Maarten Billemont
fc21bd959f Add a tip on how to solve a build error on the Raspberry Pi. 2014-10-22 22:29:05 -04:00
Maarten Billemont
2de17384ff More portable digest() 2014-10-22 22:02:17 -04:00
Maarten Billemont
85dab50996 More robust against exceptions and a few other fixes. 2014-10-22 21:54:48 -04:00
Maarten Billemont
bb97e8f3e8 Fix Core Data store migration code. 2014-10-22 20:26:22 -04:00
Maarten Billemont
f3d0368a75 Don't sync .git repos. 2014-10-22 16:03:40 -04:00
Maarten Billemont
283d555d3b Missing site resources. 2014-10-20 19:59:02 -04:00
Maarten Billemont
d909e64670 Add disclaimer. 2014-10-20 14:31:21 -04:00
Maarten Billemont
10f100186c Remove pushqueue for bash 3 compatibility. 2014-10-20 08:51:58 -04:00
Maarten Billemont
2af2351ebf Make usage text a bit more obvious. 2014-10-19 00:58:13 -04:00
Maarten Billemont
49b3fe7913 Add support for login names and security answers to C app. 2014-10-19 00:55:26 -04:00
Maarten Billemont
9d926be8ae Support for pre-downloaded dependency packages and digest verification.
[UPDATED]   Allow overriding of targets to build at command-line via target=X ./build
[ADDED]     Support pre-downloaded packages for integration with package managers.
[ADDED]     Support for package digest verification.
[UPDATED]   Skip fetching on in a method-specific way, more reliable.
2014-10-18 20:56:28 -04:00
Maarten Billemont
c3474de2ff FreeBSD build fixes. 2014-10-18 18:22:29 -04:00
Maarten Billemont
68b9b4e09a Fix git-svn/git checkouts of dependencies. 2014-10-18 17:13:01 -04:00
Maarten Billemont
b810c1032b Include signed version in release package. 2014-10-18 15:56:31 -04:00
Maarten Billemont
a4ab3c7bc9 Script to distribute C packages. 2014-10-18 15:42:49 -04:00
Maarten Billemont
039547b735 Check the presence of tools needed to build the C targets. 2014-10-18 15:38:51 -04:00
Maarten Billemont
6f741f6f2f Merge branch 'master' of github.com:Lyndir/MasterPassword 2014-10-18 15:30:58 -04:00
Maarten Billemont
38d4b761b7 Remove binaries. I don't intend to maintain binary distributions at this point. 2014-10-18 14:36:05 -04:00
Maarten Billemont
18f8ebb9dc Fix check for whether a dependency was built + improved mpw-bench output. 2014-10-17 17:10:43 -04:00
Maarten Billemont
794d064a99 Merge pull request #91 from linwiz/master
Added information to the output of mpw-bench
2014-10-17 09:19:05 -04:00
linwiz
090b274363 Added information to the output of mpw-bench 2014-10-17 08:52:15 -04:00
Maarten Billemont
25ba87f119 Make mpw-bench optional. 2014-10-15 22:18:16 -04:00
Maarten Billemont
f0b659a0c7 Add bcrypt dependency and ability to compile arbitrary dependencies in C build script. 2014-10-15 22:17:49 -04:00
Maarten Billemont
7736788920 Disable debug verbosity by default. 2014-10-15 16:27:33 -04:00
Maarten Billemont
e3be98f3ad Added mpw-bench as an extra target. 2014-10-15 16:26:09 -04:00
Maarten Billemont
d9b1b44de0 Replace editline and readline with getpass. 2014-10-15 16:03:46 -04:00
Maarten Billemont
c3c2de5d14 Ensure master password isn't lost after ending editline context. 2014-10-15 15:37:29 -04:00
Maarten Billemont
6aa50bac04 Ensure we use the correct C language standard. 2014-10-15 15:32:10 -04:00
Maarten Billemont
5268039c3d A bunch of cross-platform fixes for mpw.c + make config file optional and read master password from input instead. 2014-10-15 14:00:44 -04:00
Maarten Billemont
0d66d4660e Add code to the build script for automatically fetching and building libscrypt. 2014-10-15 08:44:41 -04:00
Maarten Billemont
e981df3c8b Fixed type of level 3 attacker.
[FIXED]     Type of level 3 attacker was string instead of integer.
2014-10-13 23:39:07 -04:00
Maarten Billemont
543ebd4bac Update provisioning profiles. 2014-10-13 22:08:36 -04:00
Maarten Billemont
e6d21e1c1d Add new question cells and fix sizing issue with store cells.
[FIXED]     Cell sizing of autosized the store cells.
[IMPROVED]  Add new question rows as soon as the last question row is used.
2014-10-13 21:56:46 -04:00
Maarten Billemont
a3ebcf0608 Fix a few spelling mistakes. 2014-10-12 12:03:57 -04:00
Maarten Billemont
556d1d3d58 Make the site more mobile-friendly. 2014-10-07 19:55:36 -04:00
Maarten Billemont
979d3a2a5a Add fallback in case the video doesn't work. 2014-10-06 23:30:41 -04:00
Maarten Billemont
480e7f192a Added a new introduction video to the Master Password website. 2014-10-06 22:03:18 -04:00
Maarten Billemont
a18793b161 Update of the site to simplify understanding Master Password and how to use it. 2014-10-05 01:22:28 -04:00
174 changed files with 15245 additions and 1797 deletions

3
.gitignore vendored
View File

@@ -32,7 +32,10 @@ Press/MasterPassword_PressKit/MasterPassword_pressrelease_*.pdf
MasterPassword/Java/**/target
# C
MasterPassword/C/VERSION
MasterPassword/C/*.o
MasterPassword/C/mpw-*.tar.gz
MasterPassword/C/mpw
MasterPassword/C/mpw-bench
MasterPassword/C/lib/*/*
!MasterPassword/C/lib/*/.source

12
.gitmodules vendored
View File

@@ -4,12 +4,18 @@
[submodule "External/InAppSettingsKit"]
path = External/InAppSettingsKit
url = git://github.com/lhunath/InAppSettingsKit.git
[submodule "External/RHStatusItemView"]
path = External/RHStatusItemView
url = git://github.com/lhunath/RHStatusItemView.git
[submodule "External/KCOrderedAccessorFix"]
path = External/KCOrderedAccessorFix
url = https://github.com/CFKevinRef/KCOrderedAccessorFix.git
[submodule "External/AttributedMarkdown"]
path = External/AttributedMarkdown
url = https://github.com/dreamwieber/AttributedMarkdown.git
[submodule "External/uicolor-utilities"]
path = External/uicolor-utilities
url = git://github.com/lhunath/uicolor-utilities.git
[submodule "External/jrswizzle"]
path = External/jrswizzle
url = git://github.com/jonmarimba/jrswizzle.git
[submodule "Site/2013-05/mpw-js/js/mpw-js"]
path = Site/2013-05/mpw-js/js/mpw-js
url = https://github.com/Lyndir/mpw-js.git

View File

@@ -1,7 +1,6 @@
language: objective-c
xcode_workspace: MasterPassword.xcworkspace
xcode_project: MasterPassword/ObjC/iOS/MasterPassword-iOS.xcodeproj
xcode_scheme: MasterPassword iOS (Development)
xcode_sdk: iphonesimulator
git:
submodules: false
before_install: ./Scripts/updateDependencies
submodules: true

View File

@@ -0,0 +1 @@
Versions/Current/Modules

View File

@@ -38,6 +38,7 @@
*
**/
OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
OBJC_EXTERN void CLSLogv(NSString *format, va_list args) NS_FORMAT_FUNCTION(1,0);
/**
*
@@ -46,6 +47,8 @@ OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
*
**/
OBJC_EXTERN void CLSNSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
OBJC_EXTERN void CLSNSLogv(NSString *format, va_list args) NS_FORMAT_FUNCTION(1,0);
@protocol CrashlyticsDelegate;

View File

@@ -0,0 +1,6 @@
framework module Crashlytics {
umbrella header "Crashlytics.h"
export *
module * { export * }
}

View File

@@ -15,13 +15,13 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.1.2</string>
<string>2.2.5</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>macosx</string>
</array>
<key>CFBundleVersion</key>
<string>9</string>
<string>39</string>
<key>DTPlatformName</key>
<string>macosx</string>
<key>MinimumOSVersion</key>

Binary file not shown.

2
External/Pearl vendored

View File

@@ -38,6 +38,7 @@
*
**/
OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
OBJC_EXTERN void CLSLogv(NSString *format, va_list args) NS_FORMAT_FUNCTION(1,0);
/**
*
@@ -46,6 +47,8 @@ OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
*
**/
OBJC_EXTERN void CLSNSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
OBJC_EXTERN void CLSNSLogv(NSString *format, va_list args) NS_FORMAT_FUNCTION(1,0);
@protocol CrashlyticsDelegate;

View File

@@ -15,13 +15,13 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.2.4</string>
<string>2.2.5</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string>
</array>
<key>CFBundleVersion</key>
<string>38</string>
<string>40</string>
<key>DTPlatformName</key>
<string>iphoneos</string>
<key>MinimumOSVersion</key>

Binary file not shown.

Binary file not shown.

1
External/jrswizzle vendored Submodule

Submodule External/jrswizzle added at 98d18aee73

1
External/uicolor-utilities vendored Submodule

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,264 @@
#!/usr/bin/env bash
# Run with -DDEBUG to enable trace-level output.
#
# TROUBLESHOOTING
# - To enable verbose algorithm/implementation debugging, use ./build -DDEBUG
# - If you see 'undefined reference to `clock_gettime'',
# try ./build -lrt instead.
# - If you see 'x86.S:202: Error: junk at end of line, first unrecognized character is `,'',
# try commenting the line in lib/bcrypt/x86.S.
#
# BUGS
# masterpassword@lyndir.com
#
# AUTHOR
# Maarten Billemont
#
cd "${BASH_SOURCE%/*}"
shopt -s extglob
set -e
[[ -e lib/scrypt/scryptenc.o ]] || { echo >&2 "Missing scrypt. First get and build the scrypt source in lib/scrypt from <$(<lib/scrypt/.source)>.\n"; exit 1; }
deps=( -I"lib/scrypt/lib" -I"lib/scrypt/libcperciva" -l "crypto_aesctr.o" -l "sha256.o" -l "crypto_scrypt-nosse.o" -l "memlimit.o" -l "scryptenc_cpuperf.o" -l"scryptenc.o" -l"crypto" -L"." -L"lib/scrypt" )
### CONFIGURATION
gcc "${deps[@]}" -Qunused-arguments -c types.c -o types.o "$@"
gcc "${deps[@]}" -Qunused-arguments -l"types.o" mpw.c -o mpw "$@"
# Targets to build.
if [[ $targets ]]; then
read -ra targets <<< "$targets"
else
# Default targets.
# Modify here or override using targets='mpw mpw-bench' ./build
targets=(
mpw # C CLI version of Master Password.
#mpw-bench # C CLI Master Password benchmark utility.
)
fi
### DEPENDENCIES
digest() {
openssl sha -sha256 -binary < "$1" | od -t x1 -An -v | tr -d '[:space:]'
}
fetch() {
if hash wget 2>/dev/null; then
wget -O "${1##*/}" "$1"
elif hash curl 2>/dev/null; then
curl "$1" > "${1##*/}"
fi
}
unpack() {
if [[ $1 = *.tar.gz || $1 = *.tgz ]]; then
tar -xvzf "$1"
elif [[ $1 = *.tar.bz2 || $1 = *.tbz2 ]]; then
tar -xvjf "$1"
elif [[ $1 = *.tar ]]; then
tar -xvf "$1"
else
echo 2>&1 "Don't know how to unpack: $1"
fi
printf 'Verifying package: %s, against digest: %s...' "$1" "$2"
[[ $(digest "$1") = $2 ]] || {
printf ' mismatch!\n'
echo 2>&1 "Downloaded package doesn't match digest."
exit 1
}
printf ' OK!\n'
files=( !("$1") )
if [[ -d $files ]] && (( ${#files[@]} == 1 )); then
mv "$files"/* .
rmdir "$files"
fi
}
fetchSource() (
source .source
if [[ $pkg && -e "${pkg##*/}" ]]; then
files=( !("${pkg##*/}") )
[[ -e $files ]] || {
echo
echo "Unpacking: ${PWD##*/}, using package..."
unpack "${pkg##*/}" "$pkg_sha256"
}
elif [[ $git ]] && hash git 2>/dev/null; then
[[ -e .git ]] || {
echo
echo "Fetching: ${PWD##*/}, using git..."
git clone "$svn" .
printf '%s' "$(git describe --always)" > "${PWD##*/}-version"
}
elif [[ $svn ]] && hash git 2>/dev/null && [[ -x "$(git --exec-path)/git-svn" ]]; then
[[ -e .git ]] || {
echo
echo "Fetching: ${PWD##*/}, using git-svn..."
git svn clone --prefix=origin/ --stdlayout "$svn" .
printf '%s' "$(git describe --always)" > "${PWD##*/}-version"
}
elif [[ $svn ]] && hash svn 2>/dev/null; then
[[ -e .svn ]] || {
echo
echo "Fetching: ${PWD##*/}, using svn..."
svn checkout "$svn/trunk" .
printf 'r%s' "$(svn info | awk '/^Revision:/{ print $2 }')" > "${PWD##*/}-version"
}
elif [[ $pkg ]]; then
files=( !("${pkg##*/}") )
[[ -e $files ]] || {
echo
echo "Fetching: ${PWD##*/}, using package..."
fetch "$pkg"
unpack "${pkg##*/}" "$pkg_sha256"
}
else
echo >&2 "error: Missing git-svn or svn."
echo >&2 "error: Please install either or manually check out the sources"
echo >&2 "error: from: $home"
echo >&2 "error: into: $PWD"
exit 1
fi
)
depend() {
echo
echo "Checking dependency: $1..."
[[ -e "lib/$1/.built" ]] && return
pushd "lib/$1"
fetchSource
echo
echo "Configuring dependency: $1..."
if [[ -e configure.ac ]]; then
if [[ ! -e configure ]]; then
# create configure using autotools.
if ! hash aclocal || ! hash automake; then
echo >&2 "Need autotools to build $1. Please install automake and autoconf."
exit 1
fi
aclocal
autoheader
autoconf
mkdir -p config.aux
automake --add-missing
fi
fi
if [[ -e configure ]]; then
./configure
fi
echo
echo "Building dependency: $1..."
if [[ -e Makefile ]]; then
if ! hash make; then
echo >&2 "Need make to build $1. Please install GNU make."
exit 1
fi
make
date > .built
else
echo >&2 "error: Don't know how to build: $1"
exit 1
fi
popd
}
### MPW
mpw() {
depend scrypt
echo
echo "Building target: $target..."
CFLAGS=(
# include paths
-I"lib/scrypt/lib" -I"lib/scrypt/libcperciva"
)
LDFLAGS=(
# library paths
-L"." -L"lib/scrypt"
# link libraries
-l"crypto"
# scrypt
"lib/scrypt/scrypt-crypto_aesctr.o"
"lib/scrypt/scrypt-sha256.o"
"lib/scrypt/scrypt-crypto_scrypt-nosse.o"
"lib/scrypt/scrypt-memlimit.o"
"lib/scrypt/scrypt-scryptenc_cpuperf.o"
"lib/scrypt/scrypt-scryptenc.o"
)
cc "${CFLAGS[@]}" -c types.c -o types.o "$@"
cc "${CFLAGS[@]}" "${LDFLAGS[@]}" "types.o" mpw.c -o mpw "$@"
echo "done! Now run ./install or use ./mpw"
}
### MPW-BENCH
mpw-bench() {
depend scrypt
depend bcrypt
echo
echo "Building target: $target..."
CFLAGS=(
# include paths
-I"lib/scrypt/lib" -I"lib/scrypt/libcperciva"
-I"lib/bcrypt"
)
LDFLAGS=(
# library paths
-L"." -L"lib/scrypt"
-L"lib/bcrypt"
# libraries
-l"crypto"
# scrypt
"lib/scrypt/scrypt-crypto_aesctr.o"
"lib/scrypt/scrypt-sha256.o"
"lib/scrypt/scrypt-crypto_scrypt-nosse.o"
"lib/scrypt/scrypt-memlimit.o"
"lib/scrypt/scrypt-scryptenc_cpuperf.o"
"lib/scrypt/scrypt-scryptenc.o"
# bcrypt
"lib/bcrypt/crypt_blowfish.o"
"lib/bcrypt/crypt_gensalt.o"
"lib/bcrypt/wrapper.o"
"lib/bcrypt/x86.o"
)
cc "${CFLAGS[@]}" -c types.c -o types.o "$@"
cc "${CFLAGS[@]}" "${LDFLAGS[@]}" "types.o" mpw-bench.c -o mpw-bench "$@"
echo "done! Now use ./mpw-bench"
}
### TARGETS
cc() {
if hash llvm-gcc 2>/dev/null; then
llvm-gcc "$@"
elif hash gcc 2>/dev/null; then
gcc -std=gnu99 "$@"
elif hash clang 2>/dev/null; then
clang "$@"
else
echo >&2 "Need a compiler. Please install GCC or LLVM."
exit 1
fi
}
echo "Will build targets: ${targets[*]}..."
for target in "${targets[@]}"; do
"$target" "$@"
done

20
MasterPassword/C/distribute Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -e
cd "${BASH_SOURCE%/*}"
tag=$(git describe)
commit=$(git describe --long --dirty)
[[ $tag && $commit = $tag-* ]] || exit 1
git show --show-signature --pretty=format:%H --quiet "$tag" > VERSION
mpwArchive=mpw-$commit.tar.gz
[[ -e $mpwArchive ]] && echo "WARNING: $mpwArchive already exists. Will overwrite."
read -n1 -p "Will prepare and release $mpwArchive. Press a key to continue or ^C to abort."
git ls-files -z . | xargs -0 tar -cvzf "$mpwArchive"
echo "$mpwArchive ready, SHA256: $(openssl sha -sha256 < "$mpwArchive")"
cd ../../Site/current
ln -sf "../../MasterPassword/C/$mpwArchive"
[[ -e $_ ]]
echo "Linked from site, please update your hyperlinks to point to http://masterpasswordapp.com/$mpwArchive"

View File

@@ -0,0 +1,3 @@
home=http://www.openwall.com/crypt/
pkg=http://www.openwall.com/crypt/crypt_blowfish-1.3.tar.gz
pkg_sha256=83fa01fca6996fe8d882b7f8e9ba0305a5664936100b01481ea3c6a8ce8d72fd

View File

@@ -1 +1,4 @@
https://code.google.com/p/scrypt/
home=https://code.google.com/p/scrypt/
svn=http://scrypt.googlecode.com/svn
pkg=http://masterpasswordapp.com/libscrypt-b12b554.tar.gz
pkg_sha256=c726daec68a345e420896f005394a948dc5a6924713ed94b684c856d4c247f0b

View File

@@ -0,0 +1,187 @@
#include <sys/time.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>
#include <pwd.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <alg/sha256.h>
#include <crypto/crypto_scrypt.h>
#include <ow-crypt.h>
#include "types.h"
#define MP_N 32768
#define MP_r 8
#define MP_p 2
#define MP_dkLen 64
#define MP_hash PearlHashSHA256
int main(int argc, char *const argv[]) {
char *userName = "Robert Lee Mitchel";
char *masterPassword = "banana colored duckling";
char *siteName = "masterpasswordapp.com";
uint32_t siteCounter = 1;
MPElementType siteType = MPElementTypeGeneratedLong;
// Start MP
struct timeval startTime;
if (gettimeofday(&startTime, NULL) != 0) {
fprintf(stderr, "Could not get time: %d\n", errno);
return 1;
}
int iterations = 100;
for (int i = 0; i < iterations; ++i) {
// Calculate the master key salt.
char *mpNameSpace = "com.lyndir.masterpassword";
const uint32_t n_userNameLength = htonl(strlen(userName));
const size_t masterKeySaltLength = strlen(mpNameSpace) + sizeof(n_userNameLength) + strlen(userName);
char *masterKeySalt = malloc( masterKeySaltLength );
if (!masterKeySalt) {
fprintf(stderr, "Could not allocate master key salt: %d\n", errno);
return 1;
}
char *mKS = masterKeySalt;
memcpy(mKS, mpNameSpace, strlen(mpNameSpace)); mKS += strlen(mpNameSpace);
memcpy(mKS, &n_userNameLength, sizeof(n_userNameLength)); mKS += sizeof(n_userNameLength);
memcpy(mKS, userName, strlen(userName)); mKS += strlen(userName);
if (mKS - masterKeySalt != masterKeySaltLength)
abort();
trc("masterKeySalt ID: %s\n", IDForBuf(masterKeySalt, masterKeySaltLength));
// Calculate the master key.
uint8_t *masterKey = malloc( MP_dkLen );
if (!masterKey) {
fprintf(stderr, "Could not allocate master key: %d\n", errno);
return 1;
}
if (crypto_scrypt( (const uint8_t *)masterPassword, strlen(masterPassword), (const uint8_t *)masterKeySalt, masterKeySaltLength, MP_N, MP_r, MP_p, masterKey, MP_dkLen ) < 0) {
fprintf(stderr, "Could not generate master key: %d\n", errno);
return 1;
}
memset(masterKeySalt, 0, masterKeySaltLength);
free(masterKeySalt);
// Calculate the site seed.
const uint32_t n_siteNameLength = htonl(strlen(siteName));
const uint32_t n_siteCounter = htonl(siteCounter);
const size_t sitePasswordInfoLength = strlen(mpNameSpace) + sizeof(n_siteNameLength) + strlen(siteName) + sizeof(n_siteCounter);
char *sitePasswordInfo = malloc( sitePasswordInfoLength );
if (!sitePasswordInfo) {
fprintf(stderr, "Could not allocate site seed: %d\n", errno);
return 1;
}
char *sPI = sitePasswordInfo;
memcpy(sPI, mpNameSpace, strlen(mpNameSpace)); sPI += strlen(mpNameSpace);
memcpy(sPI, &n_siteNameLength, sizeof(n_siteNameLength)); sPI += sizeof(n_siteNameLength);
memcpy(sPI, siteName, strlen(siteName)); sPI += strlen(siteName);
memcpy(sPI, &n_siteCounter, sizeof(n_siteCounter)); sPI += sizeof(n_siteCounter);
if (sPI - sitePasswordInfo != sitePasswordInfoLength)
abort();
uint8_t sitePasswordSeed[32];
HMAC_SHA256_Buf(masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoLength, sitePasswordSeed);
memset(masterKey, 0, MP_dkLen);
memset(sitePasswordInfo, 0, sitePasswordInfoLength);
free(masterKey);
free(sitePasswordInfo);
// Determine the cipher.
const char *cipher = CipherForType(siteType, sitePasswordSeed[0]);
trc("type %d, cipher: %s\n", siteType, cipher);
if (strlen(cipher) > 32)
abort();
// Encode the password from the seed using the cipher.
char *sitePassword = calloc(strlen(cipher) + 1, sizeof(char));
for (int c = 0; c < strlen(cipher); ++c) {
sitePassword[c] = CharacterFromClass(cipher[c], sitePasswordSeed[c + 1]);
trc("class %c, character: %c\n", cipher[c], sitePassword[c]);
}
memset(sitePasswordSeed, 0, sizeof(sitePasswordSeed));
if (i % 1 == 0)
fprintf( stderr, "\rmpw: iteration %d / %d..", i, iterations );
}
// Output timing results.
struct timeval endTime;
if (gettimeofday(&endTime, NULL) != 0) {
fprintf(stderr, "Could not get time: %d\n", errno);
return 1;
}
long long secs = (endTime.tv_sec - startTime.tv_sec);
long long usecs = (endTime.tv_usec - startTime.tv_usec);
double elapsed = secs + usecs / 1000000.0;
double mpwSpeed = iterations / elapsed;
fprintf( stdout, " done. %d iterations in %llds %lldµs -> %.2f/s\n", iterations, secs, usecs, mpwSpeed );
// Start SHA-256
if (gettimeofday(&startTime, NULL) != 0) {
fprintf(stderr, "Could not get time: %d\n", errno);
return 1;
}
iterations = 50000000;
uint8_t hash[32];
for (int i = 0; i < iterations; ++i) {
SHA256_Buf(masterPassword, strlen(masterPassword), hash);
if (i % 1000 == 0)
fprintf( stderr, "\rsha256: iteration %d / %d..", i, iterations );
}
// Output timing results.
if (gettimeofday(&endTime, NULL) != 0) {
fprintf(stderr, "Could not get time: %d\n", errno);
return 1;
}
secs = (endTime.tv_sec - startTime.tv_sec);
usecs = (endTime.tv_usec - startTime.tv_usec);
elapsed = secs + usecs / 1000000.0;
double sha256Speed = iterations / elapsed;
fprintf( stdout, " done. %d iterations in %llds %lldµs -> %.2f/s\n", iterations, secs, usecs, sha256Speed );
// Start BCrypt
if (gettimeofday(&startTime, NULL) != 0) {
fprintf(stderr, "Could not get time: %d\n", errno);
return 1;
}
int bcrypt_cost = 9;
iterations = 600;
for (int i = 0; i < iterations; ++i) {
crypt(masterPassword, crypt_gensalt("$2b$", bcrypt_cost, userName, strlen(userName)));
if (i % 10 == 0)
fprintf( stderr, "\rbcrypt (cost %d): iteration %d / %d..", bcrypt_cost, i, iterations );
}
// Output timing results.
if (gettimeofday(&endTime, NULL) != 0) {
fprintf(stderr, "Could not get time: %d\n", errno);
return 1;
}
secs = (endTime.tv_sec - startTime.tv_sec);
usecs = (endTime.tv_usec - startTime.tv_usec);
elapsed = secs + usecs / 1000000.0;
double bcrypt9Speed = iterations / elapsed;
fprintf( stdout, " done. %d iterations in %llds %lldµs -> %.2f/s\n", iterations, secs, usecs, bcrypt9Speed );
// Summarize.
fprintf( stdout, "\n== SUMMARY ==\nOn this machine,\n" );
fprintf( stdout, "mpw is %f times slower than sha256\n", sha256Speed / mpwSpeed );
fprintf( stdout, "mpw is %f times slower than bcrypt (cost 9)\n", bcrypt9Speed / mpwSpeed );
return 0;
}

View File

@@ -1,4 +1,5 @@
#define _WITH_GETLINE
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
@@ -23,6 +24,12 @@
#include <crypto/crypto_scrypt.h>
#include "types.h"
#if defined(READLINE)
#include <readline/readline.h>
#elif defined(EDITLINE)
#include <histedit.h>
#endif
#define MP_N 32768
#define MP_r 8
#define MP_p 2
@@ -52,7 +59,14 @@ void usage() {
fprintf(stderr, " -v variant The kind of content to generate.\n"
" Defaults to 'password'.\n"
" p, password | The password to log in with.\n"
" l, login | The username to log in as.\n\n");
" l, login | The username to log in as.\n"
" a, answer | The answer to a security question.\n\n");
fprintf(stderr, " -C context A variant-specific context.\n"
" Defaults to empty.\n"
" -v p, password | 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"
" | the most significant word(s) of the question.\n\n");
exit(0);
}
@@ -94,27 +108,30 @@ int main(int argc, char *const argv[]) {
const char *siteTypeString = getenv( MP_env_sitetype );
MPElementVariant siteVariant = MPElementVariantPassword;
const char *siteVariantString = NULL;
const char *siteContextString = NULL;
uint32_t siteCounter = 1;
const char *siteCounterString = getenv( MP_env_sitecounter );
// Read the options.
char opt;
while ((opt = getopt(argc, argv, "u:t:c:v:h")) != -1)
for (int opt; (opt = getopt(argc, argv, "u:t:c:v:C:h")) != -1;)
switch (opt) {
case 'h':
usage();
break;
case 'u':
userName = optarg;
break;
case 't':
siteTypeString = optarg;
break;
case 'c':
siteCounterString = optarg;
break;
case 'v':
siteVariantString = optarg;
break;
case 'c':
siteCounterString = optarg;
case 'C':
siteContextString = optarg;
break;
case 'h':
usage();
break;
case '?':
switch (optopt) {
@@ -160,6 +177,8 @@ int main(int argc, char *const argv[]) {
trc("siteVariant: %d (%s)\n", siteVariant, siteVariantString);
if (siteVariant == MPElementVariantLogin)
siteType = MPElementTypeGeneratedName;
if (siteVariant == MPElementVariantAnswer)
siteType = MPElementTypeGeneratedPhrase;
if (siteTypeString)
siteType = TypeWithName( siteTypeString );
trc("siteType: %d (%s)\n", siteType, siteTypeString);
@@ -172,11 +191,8 @@ int main(int argc, char *const argv[]) {
}
trc("mpwConfigPath: %s\n", mpwConfigPath);
FILE *mpwConfig = fopen(mpwConfigPath, "r");
if (!mpwConfig) {
fprintf(stderr, "Couldn't open configuration file: %s: %d\n", mpwConfigPath, errno);
return 1;
}
free(mpwConfigPath);
if (mpwConfig) {
char *line = NULL;
size_t linecap = 0;
ssize_t linelen;
@@ -185,18 +201,17 @@ int main(int argc, char *const argv[]) {
masterPassword = strsep(&line, "\n");
break;
}
if (!masterPassword) {
fprintf(stderr, "Missing master password for user: %s\n", userName);
return 1;
}
while (!masterPassword)
masterPassword = getpass( "Your master password: " );
trc("masterPassword: %s\n", masterPassword);
// Calculate the master key salt.
const char *mpKeyScope = ScopeForVariant(MPElementVariantPassword);
trc("key scope: %s\n", mpKeyScope);
const uint32_t n_userNameLength = htonl(strlen(userName));
size_t masterKeySaltLength = strlen(mpKeyScope) + sizeof(n_userNameLength) + strlen(userName);
char *masterKeySalt = malloc( masterKeySaltLength );
const size_t masterKeySaltLength = strlen(mpKeyScope) + sizeof(n_userNameLength) + strlen(userName);
char *masterKeySalt = (char *)malloc( masterKeySaltLength );
if (!masterKeySalt) {
fprintf(stderr, "Could not allocate master key salt: %d\n", errno);
return 1;
@@ -211,7 +226,7 @@ int main(int argc, char *const argv[]) {
trc("masterKeySalt ID: %s\n", IDForBuf(masterKeySalt, masterKeySaltLength));
// Calculate the master key.
uint8_t *masterKey = malloc( MP_dkLen );
uint8_t *masterKey = (uint8_t *)malloc( MP_dkLen );
if (!masterKey) {
fprintf(stderr, "Could not allocate master key: %d\n", errno);
return 1;
@@ -228,11 +243,14 @@ int main(int argc, char *const argv[]) {
// Calculate the site seed.
const char *mpSiteScope = ScopeForVariant(siteVariant);
trc("site scope: %s\n", mpSiteScope);
trc("site scope: %s, context: %s\n", mpSiteScope, siteContextString == NULL? "<empty>": siteContextString);
const uint32_t n_siteNameLength = htonl(strlen(siteName));
const uint32_t n_siteCounter = htonl(siteCounter);
const uint32_t n_siteContextLength = siteContextString == NULL? 0: htonl(strlen(siteContextString));
size_t sitePasswordInfoLength = strlen(mpSiteScope) + sizeof(n_siteNameLength) + strlen(siteName) + sizeof(n_siteCounter);
char *sitePasswordInfo = malloc( sitePasswordInfoLength );
if (siteContextString)
sitePasswordInfoLength += sizeof(n_siteContextLength) + strlen(siteContextString);
char *sitePasswordInfo = (char *)malloc( sitePasswordInfoLength );
if (!sitePasswordInfo) {
fprintf(stderr, "Could not allocate site seed: %d\n", errno);
return 1;
@@ -243,9 +261,13 @@ int main(int argc, char *const argv[]) {
memcpy(sPI, &n_siteNameLength, sizeof(n_siteNameLength)); sPI += sizeof(n_siteNameLength);
memcpy(sPI, siteName, strlen(siteName)); sPI += strlen(siteName);
memcpy(sPI, &n_siteCounter, sizeof(n_siteCounter)); sPI += sizeof(n_siteCounter);
if (siteContextString) {
memcpy(sPI, &n_siteContextLength, sizeof(n_siteContextLength)); sPI += sizeof(n_siteContextLength);
memcpy(sPI, siteContextString, strlen(siteContextString)); sPI += strlen(siteContextString);
}
if (sPI - sitePasswordInfo != sitePasswordInfoLength)
abort();
trc("seed from: hmac-sha256(masterKey, %s | %s | %s | %s)\n", mpSiteScope, Hex(&n_siteNameLength, sizeof(n_siteNameLength)), siteName, Hex(&n_siteCounter, sizeof(n_siteCounter)));
trc("seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n", mpSiteScope, Hex(&n_siteNameLength, sizeof(n_siteNameLength)), siteName, Hex(&n_siteCounter, sizeof(n_siteCounter)), Hex(&n_siteContextLength, sizeof(n_siteContextLength)), siteContextString);
trc("sitePasswordInfo ID: %s\n", IDForBuf(sitePasswordInfo, sitePasswordInfoLength));
uint8_t sitePasswordSeed[32];
@@ -263,7 +285,7 @@ int main(int argc, char *const argv[]) {
abort();
// Encode the password from the seed using the cipher.
char *sitePassword = calloc(strlen(cipher) + 1, sizeof(char));
char *sitePassword = (char *)calloc(strlen(cipher) + 1, sizeof(char));
for (int c = 0; c < strlen(cipher); ++c) {
sitePassword[c] = CharacterFromClass(cipher[c], sitePasswordSeed[c + 1]);
trc("class %c, character: %c\n", cipher[c], sitePassword[c]);

View File

@@ -50,19 +50,19 @@ const char *CipherForType(MPElementType type, uint8_t seedByte) {
switch (type) {
case MPElementTypeGeneratedMaximum: {
char *ciphers[] = { "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" };
const char *ciphers[] = { "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" };
return ciphers[seedByte % 2];
}
case MPElementTypeGeneratedLong: {
char *ciphers[] = { "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno", "CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno", "CvcvnoCvccCvcv", "CvcvCvccnoCvcv", "CvcvCvccCvcvno", "CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", "CvcvCvcvCvccno", "CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno", "CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno", "CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" };
const char *ciphers[] = { "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno", "CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno", "CvcvnoCvccCvcv", "CvcvCvccnoCvcv", "CvcvCvccCvcvno", "CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", "CvcvCvcvCvccno", "CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno", "CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno", "CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" };
return ciphers[seedByte % 21];
}
case MPElementTypeGeneratedMedium: {
char *ciphers[] = { "CvcnoCvc", "CvcCvcno" };
const char *ciphers[] = { "CvcnoCvc", "CvcCvcno" };
return ciphers[seedByte % 2];
}
case MPElementTypeGeneratedBasic: {
char *ciphers[] = { "aaanaaan", "aannaaan", "aaannaaa" };
const char *ciphers[] = { "aaanaaan", "aannaaan", "aaannaaa" };
return ciphers[seedByte % 3];
}
case MPElementTypeGeneratedShort: {
@@ -75,7 +75,7 @@ const char *CipherForType(MPElementType type, uint8_t seedByte) {
return "cvccvcvcv";
}
case MPElementTypeGeneratedPhrase: {
char *ciphers[] = { "cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" };
const char *ciphers[] = { "cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" };
return ciphers[seedByte % 3];
}
default: {
@@ -95,6 +95,8 @@ const MPElementVariant VariantWithName(const char *variantName) {
return MPElementVariantPassword;
if (0 == strcmp(lowerVariantName, "l") || 0 == strcmp(lowerVariantName, "login"))
return MPElementVariantLogin;
if (0 == strcmp(lowerVariantName, "a") || 0 == strcmp(lowerVariantName, "answer"))
return MPElementVariantAnswer;
fprintf(stderr, "Not a variant name: %s", lowerVariantName);
abort();
@@ -108,6 +110,9 @@ const char *ScopeForVariant(MPElementVariant variant) {
case MPElementVariantLogin: {
return "com.lyndir.masterpassword.login";
}
case MPElementVariantAnswer: {
return "com.lyndir.masterpassword.answer";
}
default: {
fprintf(stderr, "Unknown variant: %d", variant);
abort();
@@ -170,7 +175,7 @@ const char *IDForBuf(const void *buf, size_t length) {
uint8_t hash[32];
SHA256_Buf(buf, length, hash);
char *id = calloc(65, sizeof(char));
char *id = (char *)calloc(65, sizeof(char));
for (int kH = 0; kH < 32; kH++)
sprintf(&(id[kH * 2]), "%02X", hash[kH]);
@@ -178,7 +183,7 @@ const char *IDForBuf(const void *buf, size_t length) {
}
const char *Hex(const void *buf, size_t length) {
char *id = calloc(length*2+1, sizeof(char));
char *id = (char *)calloc(length*2+1, sizeof(char));
for (int kH = 0; kH < length; kH++)
sprintf(&(id[kH * 2]), "%02X", ((const uint8_t*)buf)[kH]);
return id;

View File

@@ -11,6 +11,8 @@ typedef enum {
MPElementVariantPassword,
/** Generate the login name to log in as. */
MPElementVariantLogin,
/** Generate the answer to a security question. */
MPElementVariantAnswer,
} MPElementVariant;
typedef enum {

View File

@@ -169,6 +169,8 @@ PearlAssociatedObjectProperty( NSMutableArray*, ProductObservers, productObserve
for (id<MPInAppDelegate> productObserver in self.productObservers)
[productObserver updateWithTransaction:transaction];
}
if (![[NSUserDefaults standardUserDefaults] synchronize])
wrn( @"Couldn't synchronize after transaction updates." );
}
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {

View File

@@ -122,10 +122,8 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
// No more methods left, fail if key still not known.
if (!tryKey) {
if (password) {
if (password)
inf( @"Login failed for: %@", user.userID );
MPCheckpoint( MPCheckpointSignInFailed, nil );
}
return NO;
}
@@ -159,7 +157,6 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
}];
[[NSNotificationCenter defaultCenter] postNotificationName:MPSignedInNotification object:self];
MPCheckpoint( MPCheckpointSignedIn, nil );
return YES;
}

View File

@@ -16,6 +16,7 @@
@property(strong, nonatomic, readonly) MPKey *key;
@property(strong, nonatomic, readonly) NSManagedObjectID *activeUserOID;
@property(strong, nonatomic, readonly) NSPersistentStoreCoordinator *storeCoordinator;
+ (instancetype)get;

View File

@@ -6,15 +6,16 @@
// Copyright (c) 2011 Lyndir. All rights reserved.
//
#import <StoreKit/StoreKit.h>
#import "MPAppDelegate_Shared.h"
#import "MPAppDelegate_Store.h"
#import "MPAppDelegate_Key.h"
#import "NSManagedObjectModel+KCOrderedAccessorFix.h"
@interface MPAppDelegate_Shared ()
@property(strong, nonatomic) MPKey *key;
@property(strong, nonatomic) NSManagedObjectID *activeUserOID;
@property(strong, nonatomic) NSPersistentStoreCoordinator *storeCoordinator;
@end
@@ -31,6 +32,18 @@
#endif
}
- (instancetype)init {
if (!(self = [super init]))
return nil;
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
[model kc_generateOrderedSetAccessors];
self.storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
return self;
}
- (MPUserEntity *)activeUserForMainThread {
return [self activeUserInContext:[MPAppDelegate_Shared managedObjectContextForMainThreadIfReady]];

View File

@@ -7,8 +7,6 @@
//
#import "MPAppDelegate_Store.h"
#import "MPGeneratedSiteEntity.h"
#import "NSManagedObjectModel+KCOrderedAccessorFix.h"
#if TARGET_OS_IPHONE
#define STORE_OPTIONS NSPersistentStoreFileProtectionKey : NSFileProtectionComplete,
@@ -16,7 +14,7 @@
#define STORE_OPTIONS
#endif
#define MPStoreMigrationLevelKey @"MPMigrationLevelLocalStoreKey"
#define MPMigrationLevelLocalStoreKey @"MPMigrationLevelLocalStoreKey"
typedef NS_ENUM( NSInteger, MPStoreMigrationLevel ) {
MPStoreMigrationLevelV1,
@@ -27,9 +25,7 @@ typedef NS_ENUM( NSInteger, MPStoreMigrationLevel ) {
@implementation MPAppDelegate_Shared(Store)
PearlAssociatedObjectProperty( id, SaveObserver, saveObserver );
PearlAssociatedObjectProperty( NSPersistentStoreCoordinator*, PersistentStoreCoordinator, persistentStoreCoordinator );
PearlAssociatedObjectProperty( NSOperationQueue *, StoreQueue, storeQueue );
PearlAssociatedObjectProperty( NSManagedObjectContext*, PrivateManagedObjectContext, privateManagedObjectContext );
@@ -56,7 +52,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
return NO;
[mainManagedObjectContext performBlock:^{
@try {
mocBlock( mainManagedObjectContext );
}
@catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}];
return YES;
@@ -69,7 +70,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
return NO;
[mainManagedObjectContext performBlockAndWait:^{
@try {
mocBlock( mainManagedObjectContext );
}
@catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}];
return YES;
@@ -84,7 +90,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
moc.parentContext = privateManagedObjectContextIfReady;
[moc performBlock:^{
@try {
mocBlock( moc );
}
@catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}];
return YES;
@@ -99,7 +110,12 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
moc.parentContext = privateManagedObjectContextIfReady;
[moc performBlockAndWait:^{
@try {
mocBlock( moc );
}
@catch (NSException *exception) {
err( @"While performing managed block:\n%@", [exception fullDescription] );
}
}];
return YES;
@@ -123,20 +139,28 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
inDomains:NSUserDomainMask] lastObject];
return [[[applicationSupportURL
URLByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier isDirectory:YES]
URLByAppendingPathComponent:@"UbiquityStore" isDirectory:NO]
URLByAppendingPathComponent:@"MasterPassword" isDirectory:NO]
URLByAppendingPathExtension:@"sqlite"];
}
- (void)loadStore {
@synchronized (self) {
static dispatch_once_t once = 0;
dispatch_once( &once, ^{
(self.storeQueue = [NSOperationQueue new]).maxConcurrentOperationCount = 1;
} );
// Do nothing if already fully set up, otherwise (re-)load the store.
if (self.persistentStoreCoordinator && self.saveObserver && self.mainManagedObjectContext && self.privateManagedObjectContext)
if (self.storeCoordinator && self.mainManagedObjectContext && self.privateManagedObjectContext)
return;
[self.storeQueue addOperationWithBlock:^{
// Do nothing if already fully set up, otherwise (re-)load the store.
if (self.storeCoordinator && self.mainManagedObjectContext && self.privateManagedObjectContext)
return;
// Unregister any existing observers and contexts.
if (self.saveObserver)
[[NSNotificationCenter defaultCenter] removeObserver:self.saveObserver];
PearlRemoveNotificationObserversFrom( self.mainManagedObjectContext );
[self.mainManagedObjectContext performBlockAndWait:^{
[self.mainManagedObjectContext reset];
self.mainManagedObjectContext = nil;
@@ -153,13 +177,31 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
// Check if migration is necessary.
[self migrateStore];
// Create a new store coordinator.
if (!self.persistentStoreCoordinator) {
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
[model kc_generateOrderedSetAccessors];
self.persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
}
// Install managed object contexts and observers.
self.privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[self.privateManagedObjectContext performBlockAndWait:^{
self.privateManagedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
self.privateManagedObjectContext.persistentStoreCoordinator = self.storeCoordinator;
}];
self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
self.mainManagedObjectContext.parentContext = self.privateManagedObjectContext;
// When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext.
PearlAddNotificationObserverTo( self.mainManagedObjectContext, NSManagedObjectContextDidSaveNotification,
self.privateManagedObjectContext, nil, ^(NSManagedObjectContext *mainManagedObjectContext, NSNotification *note) {
[mainManagedObjectContext performBlock:^{
@try {
[mainManagedObjectContext mergeChangesFromContextDidSaveNotification:note];
}
@catch (NSException *exception) {
err( @"While merging changes:\n%@",[exception fullDescription] );
}
}];
} );
// Create a new store coordinator.
NSError *error = nil;
NSURL *localStoreURL = [self localStoreURL];
if (![[NSFileManager defaultManager] createDirectoryAtURL:[localStoreURL URLByDeletingLastPathComponent]
@@ -167,7 +209,7 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
err( @"Couldn't create our application support directory: %@", [error fullDescription] );
return;
}
if (![self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self localStoreURL]
if (![self.storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self localStoreURL]
options:@{
NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES,
@@ -180,25 +222,6 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
}
self.storeCorrupted = @NO;
// Create our contexts and observer.
self.privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[self.privateManagedObjectContext performBlockAndWait:^{
self.privateManagedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
self.privateManagedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator;
}];
self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
self.mainManagedObjectContext.parentContext = self.privateManagedObjectContext;
self.saveObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification
object:self.privateManagedObjectContext queue:nil usingBlock:
^(NSNotification *note) {
// When privateManagedObjectContext is saved, import the changes into mainManagedObjectContext.
[self.mainManagedObjectContext performBlock:^{
[self.mainManagedObjectContext mergeChangesFromContextDidSaveNotification:note];
}];
}];
#if TARGET_OS_IPHONE
PearlAddNotificationObserver( UIApplicationWillTerminateNotification, UIApp, [NSOperationQueue mainQueue],
^(MPAppDelegate_Shared *self, NSNotification *note) {
@@ -220,15 +243,14 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
[MPAppDelegate_Shared managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
[self findAndFixInconsistenciesSaveInContext:context];
}];
}
}];
}
- (void)deleteAndResetStore {
@synchronized (self) {
// Unregister any existing observers and contexts.
if (self.saveObserver)
[[NSNotificationCenter defaultCenter] removeObserver:self.saveObserver];
PearlRemoveNotificationObserversFrom( self.mainManagedObjectContext );
[self.mainManagedObjectContext performBlockAndWait:^{
[self.mainManagedObjectContext reset];
self.mainManagedObjectContext = nil;
@@ -238,11 +260,10 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
self.privateManagedObjectContext = nil;
}];
NSError *error = nil;
for (NSPersistentStore *store in self.persistentStoreCoordinator.persistentStores) {
if (![self.persistentStoreCoordinator removePersistentStore:store error:&error])
for (NSPersistentStore *store in self.storeCoordinator.persistentStores) {
if (![self.storeCoordinator removePersistentStore:store error:&error])
err( @"Couldn't remove persistence store from coordinator: %@", [error fullDescription] );
}
self.persistentStoreCoordinator = nil;
if (![[NSFileManager defaultManager] removeItemAtURL:self.localStoreURL error:&error])
err( @"Couldn't remove persistence store at URL %@: %@", self.localStoreURL, [error fullDescription] );
@@ -287,23 +308,25 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
- (void)migrateStore {
MPStoreMigrationLevel migrationLevel = (signed)[[NSUserDefaults standardUserDefaults] integerForKey:MPStoreMigrationLevelKey];
MPStoreMigrationLevel migrationLevel = (signed)[[NSUserDefaults standardUserDefaults] integerForKey:MPMigrationLevelLocalStoreKey];
if (migrationLevel >= MPStoreMigrationLevelCurrent)
// Local store up-to-date.
return;
inf( @"Local store migration level: %d (current %d)", (signed)migrationLevel, (signed)MPStoreMigrationLevelCurrent );
if (migrationLevel == MPStoreMigrationLevelV1 && ![self migrateV1LocalStore]) {
if (migrationLevel <= MPStoreMigrationLevelV1 && ![self migrateV1LocalStore]) {
inf( @"Failed to migrate old V1 to new local store." );
return;
}
if (migrationLevel == MPStoreMigrationLevelV2 && ![self migrateV2LocalStore]) {
if (migrationLevel <= MPStoreMigrationLevelV2 && ![self migrateV2LocalStore]) {
inf( @"Failed to migrate old V2 to new local store." );
return;
}
[[NSUserDefaults standardUserDefaults] setInteger:MPStoreMigrationLevelCurrent forKey:MPStoreMigrationLevelKey];
[[NSUserDefaults standardUserDefaults] setInteger:MPStoreMigrationLevelCurrent forKey:MPMigrationLevelLocalStoreKey];
inf( @"Successfully migrated old to new local store." );
if (![[NSUserDefaults standardUserDefaults] synchronize])
wrn( @"Couldn't synchronize after store migration." );
}
- (BOOL)migrateV1LocalStore {
@@ -319,14 +342,16 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
inf( @"Migrating V1 local store" );
NSURL *newLocalStoreURL = [self localStoreURL];
NSError *error = nil;
if (![[NSFileManager defaultManager] createDirectoryAtURL:[newLocalStoreURL URLByDeletingLastPathComponent]
withIntermediateDirectories:YES attributes:nil error:&error]) {
err( @"Couldn't create our application support directory: %@", [error fullDescription] );
return NO;
if (![[NSFileManager defaultManager] fileExistsAtPath:newLocalStoreURL.path isDirectory:NULL]) {
inf( @"New local store already exists." );
return YES;
}
if (![[NSFileManager defaultManager] moveItemAtURL:oldLocalStoreURL toURL:newLocalStoreURL error:&error]) {
err( @"Couldn't move the old store to the new location: %@", [error fullDescription] );
NSError *error = nil;
if (![NSPersistentStore migrateStore:oldLocalStoreURL withOptions:@{ STORE_OPTIONS }
toStore:newLocalStoreURL withOptions:@{ STORE_OPTIONS }
model:nil error:&error]) {
err( @"Couldn't migrate the old store to the new location: %@", [error fullDescription] );
return NO;
}
@@ -358,14 +383,22 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
inf( @"Migrating V2 local store" );
NSURL *newLocalStoreURL = [self localStoreURL];
NSError *error = nil;
if (![[NSFileManager defaultManager] createDirectoryAtURL:[newLocalStoreURL URLByDeletingLastPathComponent]
withIntermediateDirectories:YES attributes:nil error:&error]) {
err( @"Couldn't create our application support directory: %@", [error fullDescription] );
return NO;
if ([[NSFileManager defaultManager] fileExistsAtPath:newLocalStoreURL.path isDirectory:NULL]) {
inf( @"New local store already exists." );
return YES;
}
if (![[NSFileManager defaultManager] moveItemAtURL:oldLocalStoreURL toURL:newLocalStoreURL error:&error]) {
err( @"Couldn't move the old store to the new location: %@", [error fullDescription] );
NSError *error = nil;
if (![NSPersistentStore migrateStore:oldLocalStoreURL withOptions:@{
NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES,
STORE_OPTIONS
} toStore:newLocalStoreURL withOptions:@{
NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES,
STORE_OPTIONS
} model:nil error:&error]) {
err( @"Couldn't migrate the old store to the new location: %@", [error fullDescription] );
return NO;
}
@@ -697,6 +730,10 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
// Create new site.
NSString *typeEntityName = [MPAlgorithmForVersion( version ) classNameOfType:type];
if (!typeEntityName) {
err( @"Invalid site type in import file: %@ has type %lu", siteName, (long)type );
return MPImportResultInternalError;
}
MPSiteEntity *site = [NSEntityDescription insertNewObjectForEntityForName:typeEntityName inManagedObjectContext:context];
site.name = siteName;
site.loginName = loginName;
@@ -721,7 +758,6 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
return MPImportResultInternalError;
inf( @"Import completed successfully." );
MPCheckpoint( MPCheckpointSitesImported, nil );
[[NSNotificationCenter defaultCenter] postNotificationName:MPSitesImportedNotification object:nil userInfo:@{
MPSitesImportedNotificationUserKey : user
@@ -789,10 +825,6 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
[(loginName?: @"") UTF8String], [siteName UTF8String], content?: @""];
}
MPCheckpoint( MPCheckpointSitesExported, @{
@"showPasswords" : @(revealPasswords)
} );
return export;
}

View File

@@ -23,7 +23,7 @@
}
@catch (NSException *exception) {
success = NO;
err( @"While saving: %@", exception );
err( @"While saving: %@", [exception fullDescription] );
}
}];
}
@@ -128,10 +128,15 @@
- (NSString *)debugDescription {
@try {
return strf( @"{%@: name=%@, user=%@, type=%lu, uses=%ld, lastUsed=%@, version=%ld, loginName=%@, requiresExplicitMigration=%d}",
NSStringFromClass( [self class] ), self.name, self.user.name, (long)self.type, (long)self.uses, self.lastUsed,
(long)self.version,
self.loginName, self.requiresExplicitMigration );
} @catch (NSException *exception) {
return strf( @"{%@: inaccessible: %@}",
NSStringFromClass( [self class] ), [exception fullDescription] );
}
}
- (BOOL)tryMigrateExplicitly:(BOOL)explicit {

View File

@@ -47,35 +47,6 @@ typedef NS_ENUM(NSUInteger, MPSiteType) {
#define MPErrorDomain @"MPErrorDomain"
#define MPCheckpointHelpChapter @"MPCheckpointHelpChapter"
#define MPCheckpointCopyToPasteboard @"MPCheckpointCopyToPasteboard"
#define MPCheckpointCopyLoginNameToPasteboard @"MPCheckpointCopyLoginNameToPasteboard"
#define MPCheckpointResetPasswordCounter @"MPCheckpointResetPasswordCounter"
#define MPCheckpointIncrementPasswordCounter @"MPCheckpointIncrementPasswordCounter"
#define MPCheckpointEditPassword @"MPCheckpointEditPassword"
#define MPCheckpointEditLoginName @"MPCheckpointEditLoginName"
#define MPCheckpointUseType @"MPCheckpointUseType"
#define MPCheckpointDeleteSite @"MPCheckpointDeleteSite"
#define MPCheckpointShowGuide @"MPCheckpointShowGuide"
#define MPCheckpointShowSetup @"MPCheckpointShowSetup"
#define MPCheckpointChangeMP @"MPCheckpointChangeMP"
#define MPCheckpointMPErrorUbiquity @"MPCheckpointMPErrorUbiquity"
#define MPCheckpointLocalStoreReset @"MPCheckpointLocalStoreReset"
#define MPCheckpointCloudStoreReset @"MPCheckpointCloudStoreReset"
#define MPCheckpointSignInFailed @"MPCheckpointSignInFailed"
#define MPCheckpointSignedIn @"MPCheckpointSignedIn"
#define MPCheckpointConfig @"MPCheckpointConfig"
#define MPCheckpointCloud @"MPCheckpointCloud"
#define MPCheckpointSitesImported @"MPCheckpointSitesImported"
#define MPCheckpointSitesExported @"MPCheckpointSitesExported"
#define MPCheckpointExplicitMigration @"MPCheckpointExplicitMigration"
#define MPCheckpointReview @"MPCheckpointReview"
#define MPCheckpointApps @"MPCheckpointApps"
#define MPCheckpointApp @"MPCheckpointApp"
#define MPCheckpointEmergencyGenerator @"MPCheckpointEmergencyGenerator"
#define MPCheckpointLogs @"MPCheckpointLogs"
#define MPCheckpointStarted @"MPCheckpointStarted"
#define MPSignedInNotification @"MPSignedInNotification"
#define MPSignedOutNotification @"MPSignedOutNotification"
#define MPKeyForgottenNotification @"MPKeyForgottenNotification"
@@ -86,8 +57,3 @@ typedef NS_ENUM(NSUInteger, MPSiteType) {
#define MPSitesImportedNotificationUserKey @"MPSitesImportedNotificationUserKey"
#define MPInconsistenciesFixResultUserKey @"MPInconsistenciesFixResultUserKey"
static void MPCheckpoint(NSString *checkpoint, NSDictionary *attributes) {
inf(@"%@: %@", checkpoint, attributes);
}

View File

@@ -8,13 +8,12 @@
#import <Cocoa/Cocoa.h>
#import "MPAppDelegate_Shared.h"
#import "RHStatusItemView.h"
#import "MPPasswordWindowController.h"
#import "MPInitialWindowController.h"
@interface MPMacAppDelegate : MPAppDelegate_Shared<NSApplicationDelegate>
@property(nonatomic, strong) RHStatusItemView *statusView;
@property(nonatomic, strong) NSStatusItem *statusView;
@property(nonatomic, strong) MPPasswordWindowController *passwordWindowController;
@property(nonatomic, strong) MPInitialWindowController *initialWindowController;
@property(nonatomic, weak) IBOutlet NSMenuItem *lockItem;

View File

@@ -9,8 +9,6 @@
#import "MPMacAppDelegate.h"
#import "MPAppDelegate_Key.h"
#import "MPAppDelegate_Store.h"
#import "MPPasswordWindowController.h"
#import "PearlProfiler.h"
#import <Carbon/Carbon.h>
#import <ServiceManagement/ServiceManagement.h>
@@ -75,29 +73,37 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
} forKeyPath:@"activeUser" options:0 context:nil];
// Status item.
self.statusView = [[RHStatusItemView alloc] initWithStatusBarItem:
[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength]];
self.statusView = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
self.statusView.image = [NSImage imageNamed:@"menu-icon"];
self.statusView.image.template = YES;
self.statusView.menu = self.statusMenu;
self.statusView.target = self;
self.statusView.action = @selector( showMenu );
[[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidChangeNotification object:nil
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, self.storeCoordinator, nil,
^(id self, NSNotification *note) {
PearlMainQueue( ^{
[self updateUsers];
}];
[[NSNotificationCenter defaultCenter] addObserverForName:USMStoreDidImportChangesNotification object:nil
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
} );
} );
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, self.storeCoordinator, nil,
^(id self, NSNotification *note) {
PearlMainQueue( ^{
[self updateUsers];
}];
[[NSNotificationCenter defaultCenter] addObserverForName:MPCheckConfigNotification object:nil
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
} );
} );
PearlAddNotificationObserver( MPCheckConfigNotification, nil, nil,
^(MPMacAppDelegate *self, NSNotification *note) {
PearlMainQueue( ^{
NSString *key = note.object;
if (!key || [key isEqualToString:NSStringFromSelector( @selector( hidePasswords ) )])
if (!key || [key isEqualToString:NSStringFromSelector( @
selector( hidePasswords ) )])
self.hidePasswordsItem.state = [[MPConfig get].hidePasswords boolValue]? NSOnState: NSOffState;
if (!key || [key isEqualToString:NSStringFromSelector( @selector( rememberLogin ) )])
if (!key || [key isEqualToString:NSStringFromSelector( @
selector( rememberLogin ) )])
self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState;
}];
} );
} );
[self updateUsers];
// Global hotkey.
@@ -178,12 +184,9 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
NSArray *jobs = (__bridge_transfer NSArray *)SMCopyAllJobDictionaries( kSMDomainUserLaunchd );
for (NSDictionary *job in jobs)
if ([LOGIN_HELPER_BUNDLE_ID isEqualToString:[job objectForKey:@"Label"]]) {
dbg( @"loginItemEnabled: %@", @([[job objectForKey:@"OnDemand"] boolValue]) );
return [[job objectForKey:@"OnDemand"] boolValue];
}
if ([LOGIN_HELPER_BUNDLE_ID isEqualToString:job[@"Label"]])
return [job[@"OnDemand"] boolValue];
dbg( @"loginItemEnabled: not found" );
return NO;
}
@@ -305,9 +308,9 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (IBAction)togglePreference:(id)sender {
if (sender == self.hidePasswordsItem)
[MPConfig get].hidePasswords = [NSNumber numberWithBool:![[MPConfig get].hidePasswords boolValue]];
[MPConfig get].hidePasswords = @(![[MPConfig get].hidePasswords boolValue]);
if (sender == self.rememberPasswordItem)
[MPConfig get].rememberLogin = [NSNumber numberWithBool:![[MPConfig get].rememberLogin boolValue]];
[MPConfig get].rememberLogin = @(![[MPConfig get].rememberLogin boolValue]);
if (sender == self.openAtLoginItem)
[self setLoginItemEnabled:self.openAtLoginItem.state != NSOnState];
if (sender == self.savePasswordItem) {
@@ -391,7 +394,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (IBAction)showPopup:(id)sender {
[self.statusView popUpMenu];
[self.statusView popUpStatusItemMenu:self.statusView.menu];
}
- (IBAction)showPasswordWindow:(id)sender {
@@ -409,13 +412,10 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
}
// Don't show window if we weren't already running (ie. if we haven't been activated before).
PearlProfiler *profiler = [PearlProfiler profilerForTask:@"passwordWindowController"];
if (!self.passwordWindowController)
self.passwordWindowController = [[MPPasswordWindowController alloc] initWithWindowNibName:@"MPPasswordWindowController"];
[profiler finishJob:@"init"];
[self.passwordWindowController showWindow:self];
[profiler finishJob:@"show"];
}
#pragma mark - Private
@@ -464,7 +464,9 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
[[[NSFileCoordinator alloc] initWithFilePresenter:nil] coordinateWritingItemAtURL:savePanel.URL options:0 error:&coordinateError
byAccessor:^(NSURL *newURL) {
NSError *writeError = nil;
if (![exportedSites writeToURL:newURL atomically:NO encoding:NSUTF8StringEncoding error:&writeError])
if (![exportedSites writeToURL:newURL atomically:NO
encoding:NSUTF8StringEncoding
error:&writeError])
PearlMainQueue( ^{
[[NSAlert alertWithError:writeError] runModal];
} );
@@ -543,7 +545,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
[self updateMenuItems];
[self.statusView popUpMenu];
[self.statusView popUpStatusItemMenu:self.statusView.menu];
}
- (void)updateMenuItems {
@@ -596,30 +598,6 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
}
}
#pragma mark - UbiquityStoreManagerDelegate
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager didLoadStoreForCoordinator:(NSPersistentStoreCoordinator *)coordinator
isCloud:(BOOL)isCloudStore {
[super ubiquityStoreManager:manager didLoadStoreForCoordinator:coordinator isCloud:isCloudStore];
if (isCloudStore) {
NSAlert *alert = [NSAlert new];
alert.messageText = @"iCloud Support Deprecated";
alert.informativeText = @"Master Password is moving away from iCloud due to limited platform support and reliability issues. "
@"\n\nMaster Password's generated passwords do not require syncing. "
@"Your sites will always have the same passwords on all your devices. "
@"\n\niCloud continues to work for now but will be deactivated in a future update. "
@"Disable iCloud now to copy your iCloud sites to your device and avoid losing them when iCloud becomes discontinued.";
[alert addButtonWithTitle:@"Disable iCloud"];
[alert addButtonWithTitle:@"Ignore For Now"];
NSInteger response = [alert runModal];
if (response == NSAlertFirstButtonReturn)
[[self storeManager] migrateCloudToLocal];
}
}
#pragma mark - PearlConfigDelegate
- (void)didUpdateConfigForKey:(SEL)configKey fromValue:(id)oldValue {

View File

@@ -0,0 +1,23 @@
/**
* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
*
* See the enclosed file LICENSE for license information (LGPLv3). If you did
* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
*
* @author Maarten Billemont <lhunath@lyndir.com>
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
*/
//
// MPNoStateButton.h
// MPNoStateButton
//
// Created by lhunath on 14-10-27.
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface MPNoStateButtonCell : NSButtonCell
@end

View File

@@ -0,0 +1,31 @@
/**
* Copyright Maarten Billemont (http://www.lhunath.com, lhunath@lyndir.com)
*
* See the enclosed file LICENSE for license information (LGPLv3). If you did
* not receive this file, see http://www.gnu.org/licenses/lgpl-3.0.txt
*
* @author Maarten Billemont <lhunath@lyndir.com>
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
*/
//
// MPNoStateButton.h
// MPNoStateButton
//
// Created by lhunath on 14-10-27.
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
//
#import "MPNoStateButton.h"
@implementation MPNoStateButtonCell {
}
- (void)setState:(NSInteger)state {
[super setState:NSOnState];
}
@end

View File

@@ -20,9 +20,7 @@
#import "MPPasswordWindowController.h"
#import "MPMacAppDelegate.h"
#import "MPAppDelegate_Store.h"
#import "MPSiteModel.h"
#import "MPAppDelegate_Key.h"
#import "PearlProfiler.h"
#define MPAlertIncorrectMP @"MPAlertIncorrectMP"
#define MPAlertChangeMP @"MPAlertChangeMP"
@@ -34,11 +32,11 @@
@interface MPPasswordWindowController()
@property(nonatomic, copy) NSString *currentSiteText;
@property(nonatomic, strong) CAGradientLayer *siteGradient;
@end
@implementation MPPasswordWindowController { BOOL _skipTextChange; }
@implementation MPPasswordWindowController
#pragma mark - Life
@@ -67,7 +65,9 @@
}];
[[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillResignActiveNotification object:nil
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
#ifndef DEBUG
[self fadeOut];
#endif
}];
[[NSNotificationCenter defaultCenter] addObserverForName:MPSignedInNotification object:nil
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
@@ -118,7 +118,6 @@
- (void)doCommandBySelector:(SEL)commandSelector {
dbg( @"doCommandBySelector: %@", NSStringFromSelector( commandSelector ) );
[self handleCommand:commandSelector];
}
@@ -126,13 +125,10 @@
- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector {
dbg( @"@control:%@ textView:%@ doCommandBySelector:%@", control, fieldEditor, NSStringFromSelector( commandSelector ) );
if (control == self.siteField) {
if ([NSStringFromSelector( commandSelector ) rangeOfString:@"delete"].location == 0) {
_skipTextChange = YES;
if ([NSStringFromSelector( commandSelector ) rangeOfString:@"delete"].location == 0)
return NO;
}
}
if (control == self.securePasswordField || control == self.revealPasswordField) {
if (commandSelector == @selector( insertNewline: ))
return NO;
@@ -178,7 +174,6 @@
- (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector {
dbg( @"textView:%@doCommandBySelector:%@", textView, NSStringFromSelector( commandSelector ) );
return [self handleCommand:commandSelector];
}
@@ -309,11 +304,6 @@
#pragma mark - State
- (NSString *)query {
return [self.siteField.stringValue stringByReplacingCharactersInRange:self.siteField.currentEditor.selectedRange withString:@""]?: @"";
}
- (void)insertObject:(MPSiteModel *)model inSitesAtIndex:(NSUInteger)index {
[self.sites insertObject:model atIndex:index];
@@ -343,7 +333,7 @@
[alert addButtonWithTitle:@"Delete"];
[alert addButtonWithTitle:@"Cancel"];
[alert setMessageText:@"Delete Site?"];
[alert setInformativeText:strf( @"Do you want to delete the site named:\n\n%@", self.selectedSite.siteName )];
[alert setInformativeText:strf( @"Do you want to delete the site named:\n\n%@", self.selectedSite.name )];
[alert beginSheetModalForWindow:self.window modalDelegate:self
didEndSelector:@selector( alertDidEnd:returnCode:contextInfo: ) contextInfo:MPAlertDeleteSite];
}
@@ -354,7 +344,7 @@
[alert addButtonWithTitle:@"Save"];
[alert addButtonWithTitle:@"Cancel"];
[alert setMessageText:@"Change Login Name"];
[alert setInformativeText:strf( @"Enter the login name for: %@", self.selectedSite.siteName )];
[alert setInformativeText:strf( @"Enter the login name for: %@", self.selectedSite.name )];
NSTextField *loginField = [[NSTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )];
loginField.stringValue = self.selectedSite.loginName?: @"";
[loginField selectText:self];
@@ -388,7 +378,7 @@
[alert addButtonWithTitle:@"Save"];
[alert addButtonWithTitle:@"Cancel"];
[alert setMessageText:@"Change Password"];
[alert setInformativeText:strf( @"Enter the new password for: %@", self.selectedSite.siteName )];
[alert setInformativeText:strf( @"Enter the new password for: %@", self.selectedSite.name )];
[alert setAccessoryView:[[NSSecureTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )]];
[alert layout];
[alert beginSheetModalForWindow:self.window modalDelegate:self
@@ -404,8 +394,9 @@
MPSiteType type = [types[t] unsignedIntegerValue];
NSString *title = [site.algorithm nameOfType:type];
if (type & MPSiteTypeClassGenerated)
title = [site.algorithm generatePasswordForSiteNamed:site.siteName ofType:type
withCounter:site.counter usingKey:[MPMacAppDelegate get].key];
title = [site.algorithm generatePasswordForSiteNamed:site.name ofType:type
withCounter:site.counter
usingKey:[MPMacAppDelegate get].key];
NSButtonCell *cell = [self.passwordTypesMatrix cellAtRow:(NSInteger)t column:0];
cell.tag = type;
@@ -417,7 +408,7 @@
[alert addButtonWithTitle:@"Save"];
[alert addButtonWithTitle:@"Cancel"];
[alert setMessageText:@"Change Password Type"];
[alert setInformativeText:strf( @"Choose a new password type for: %@", site.siteName )];
[alert setInformativeText:strf( @"Choose a new password type for: %@", site.name )];
[alert setAccessoryView:self.passwordTypesBox];
[alert layout];
[alert beginSheetModalForWindow:self.window modalDelegate:self
@@ -460,9 +451,9 @@
NSUserNotification *notification = [NSUserNotification new];
notification.title = @"Password Copied";
if (selectedSite.loginName.length)
notification.subtitle = strf( @"%@ at %@", selectedSite.loginName, selectedSite.siteName );
notification.subtitle = strf( @"%@ at %@", selectedSite.loginName, selectedSite.name );
else
notification.subtitle = selectedSite.siteName;
notification.subtitle = selectedSite.name;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
else {
@@ -511,15 +502,24 @@
return;
}
PearlProfiler *profiler = [PearlProfiler profilerForTask:@"updateSites"];
NSString *query = [self query];
[profiler finishJob:@"query"];
static NSRegularExpression *fuzzyRE;
static dispatch_once_t once = 0;
dispatch_once( &once, ^{
fuzzyRE = [NSRegularExpression regularExpressionWithPattern:@"(.)" options:0 error:nil];
} );
NSString *queryString = self.siteField.stringValue;
NSString *queryPattern = [queryString stringByReplacingMatchesOfExpression:fuzzyRE withTemplate:@"*$1*"];
NSMutableArray *fuzzyGroups = [NSMutableArray new];
[fuzzyRE enumerateMatchesInString:queryString options:0 range:NSMakeRange( 0, queryString.length )
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
[fuzzyGroups addObject:[queryString substringWithRange:result.range] ];
}];
[MPMacAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(%@ == '' OR name BEGINSWITH[cd] %@) AND user == %@",
query, query, [[MPMacAppDelegate get] activeUserInContext:context]];
[profiler finishJob:@"setup fetch"];
fetchRequest.sortDescriptors = @[ [[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO] ];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(%@ == '' OR name LIKE[cd] %@) AND user == %@",
queryPattern, queryPattern, [[MPMacAppDelegate get] activeUserInContext:context]];
NSError *error = nil;
NSArray *siteResults = [context executeFetchRequest:fetchRequest error:&error];
@@ -527,43 +527,17 @@
err( @"While fetching sites for completion: %@", [error fullDescription] );
return;
}
[profiler finishJob:@"do fetch"];
NSMutableArray *newSites = [NSMutableArray arrayWithCapacity:[siteResults count]];
for (MPSiteEntity *site in siteResults)
[newSites addObject:[[MPSiteModel alloc] initWithEntity:site]];
[profiler finishJob:@"make models"];
[newSites addObject:[[MPSiteModel alloc] initWithEntity:site fuzzyGroups:fuzzyGroups]];
self.sites = newSites;
[profiler finishJob:@"update sites"];
}];
[profiler finishJob:@"done"];
}
- (void)updateSelection {
if (_skipTextChange) {
_skipTextChange = NO;
return;
}
NSString *siteName = self.selectedSite.siteName;
if (!siteName)
return;
if ([self.window isKeyWindow] && [self.siteField isEqual:[self.window firstResponder]]) {
NSRange siteNameQueryRange = [siteName rangeOfString:[self query]];
self.siteField.stringValue = siteName;
if (siteNameQueryRange.location == 0)
self.siteField.currentEditor.selectedRange =
NSMakeRange( siteNameQueryRange.length, siteName.length - siteNameQueryRange.length );
}
[self.siteTable scrollRowToVisible:(NSInteger)self.sitesController.selectionIndex];
[self updateGradient];
}
- (void)updateGradient {
NSView *siteScrollView = self.siteTable.superview.superview;
NSRect selectedCellFrame = [self.siteTable frameOfCellAtColumn:0 row:((NSInteger)self.sitesController.selectionIndex)];
@@ -590,7 +564,7 @@
- (void)copyContent:(NSString *)content {
[[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
[[NSPasteboard generalPasteboard] declareTypes:@[ NSStringPboardType ] owner:nil];
if (![[NSPasteboard generalPasteboard] setString:content forType:NSPasteboardTypeString]) {
wrn( @"Couldn't copy password to pasteboard." );
return;
@@ -607,7 +581,6 @@
if ([self.window isOnActiveSpace] && self.window.alphaValue)
return;
PearlProfiler *profiler = [PearlProfiler profilerForTask:@"fadeIn"];
CGDirectDisplayID displayID = [self.window.screen.deviceDescription[@"NSScreenNumber"] unsignedIntValue];
CGImageRef capturedImage = CGDisplayCreateImage( displayID );
if (!capturedImage || CGImageGetWidth( capturedImage ) <= 1) {
@@ -615,11 +588,9 @@
return;
}
[profiler finishJob:@"captured window: %d, on screen: %@", displayID, self.window.screen.deviceDescription];
NSImage *screenImage = [[NSImage alloc] initWithCGImage:capturedImage size:NSMakeSize(
CGImageGetWidth( capturedImage ) / self.window.backingScaleFactor,
CGImageGetHeight( capturedImage ) / self.window.backingScaleFactor )];
[profiler finishJob:@"image size: %@, bytes: %ld", NSStringFromSize( screenImage.size ), screenImage.TIFFRepresentation.length];
NSImage *smallImage = [[NSImage alloc] initWithSize:NSMakeSize(
CGImageGetWidth( capturedImage ) / 20,
@@ -631,16 +602,12 @@
operation:NSCompositeSourceOver
fraction:1.0];
[smallImage unlockFocus];
[profiler finishJob:@"small image size: %@, bytes: %ld", NSStringFromSize( screenImage.size ), screenImage.TIFFRepresentation.length];
self.blurView.image = smallImage;
[profiler finishJob:@"assigned image"];
[self.window setFrame:self.window.screen.frame display:YES];
[profiler finishJob:@"assigned frame"];
[NSAnimationContext currentContext].timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
self.window.animator.alphaValue = 1.0;
[profiler finishJob:@"animating window"];
}
- (void)fadeOut {

View File

@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13E28" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6250" systemVersion="14A389" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment defaultVersion="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6250"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPPasswordWindowController">
<connections>
<outlet property="blurView" destination="Bwc-sd-6gm" id="wNV-0x-LJn"/>
<outlet property="sitesController" destination="mcS-ik-b0n" id="cdF-BL-lfg"/>
<outlet property="inputLabel" destination="OnR-s6-d4P" id="p6G-Ut-cdu"/>
<outlet property="passwordTypesBox" destination="bZe-7q-i6q" id="Ai3-pt-i6K"/>
<outlet property="passwordTypesMatrix" destination="3fr-Fd-pxx" id="T8g-mS-lxP"/>
@@ -17,11 +16,12 @@
<outlet property="securePasswordField" destination="iGR-wo-ual" id="DGh-5i-3u4"/>
<outlet property="siteField" destination="CnS-iI-dhr" id="Ogo-lS-dcT"/>
<outlet property="siteTable" destination="xvJ-5c-vDp" id="ClP-j8-DyI"/>
<outlet property="sitesController" destination="mcS-ik-b0n" id="cdF-BL-lfg"/>
<outlet property="window" destination="QvC-M9-y7g" id="dPy-F3-9rn"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<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" transient="YES" ignoresCycle="YES" fullScreenAuxiliary="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" bottomStrut="YES"/>
@@ -32,18 +32,24 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Bwc-sd-6gm" userLabel="Screen Capture">
<rect key="frame" x="0.0" y="0.0" width="640" height="560"/>
<rect key="frame" x="-80" y="-80" width="800" height="720"/>
<contentFilters>
<ciFilter name="CIGaussianBlur">
<configuration>
<null key="inputImage"/>
<real key="inputRadius" value="40"/>
<real key="inputRadius" value="30"/>
</configuration>
</ciFilter>
<ciFilter name="CISepiaTone">
<configuration>
<null key="inputImage"/>
<real key="inputIntensity" value="0.40000000000000002"/>
<real key="inputIntensity" value="0.20000000000000001"/>
</configuration>
</ciFilter>
<ciFilter name="CIExposureAdjust">
<configuration>
<real key="inputEV" value="0.0"/>
<null key="inputImage"/>
</configuration>
</ciFilter>
</contentFilters>
@@ -51,13 +57,13 @@
</imageView>
<secureTextField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="iGR-wo-ual" userLabel="Secure Master Password">
<rect key="frame" x="18" y="258" width="604" height="44"/>
<shadow key="shadow" blurRadius="1">
<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>
<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"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
@@ -86,13 +92,13 @@
</secureTextField>
<textField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="v80-wd-hUR" userLabel="Reveal Master Password">
<rect key="frame" x="18" y="258" width="604" height="44"/>
<shadow key="shadow" blurRadius="1">
<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>
<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"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
@@ -123,11 +129,11 @@
<outlet property="delegate" destination="-2" id="2nK-Rc-uyR"/>
</connections>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R46-fx-n14" userLabel="Reset Master Password">
<rect key="frame" x="242" y="19" width="156" height="20"/>
<buttonCell key="cell" type="inline" title="Reset My Master Password" bezelStyle="inline" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="B7Z-72-fVP">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="11" name="HelveticaNeue-Bold"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R46-fx-n14" userLabel="Reset Button">
<rect key="frame" x="230" y="19" width="181" height="19"/>
<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"/>
<font key="font" metaFont="systemBold" size="12"/>
</buttonCell>
<connections>
<action selector="resetMasterPassword:" target="-2" id="kCy-X0-teH"/>
@@ -144,11 +150,10 @@
<rect key="frame" x="0.0" y="0.0" width="512" height="147"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" selectionHighlightStyle="sourceList" 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="147"/>
<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">
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="deviceWhite"/>
<color key="gridColor" name="selectedControlColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn editable="NO" width="512" minWidth="512" maxWidth="512" id="S71-gk-yF7">
@@ -170,17 +175,17 @@
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="ydd-Rv-tra">
<rect key="frame" x="-2" y="2" width="516" height="29"/>
<shadow key="shadow" blurRadius="1">
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.80000000000000004" colorSpace="calibratedWhite"/>
</shadow>
<textFieldCell key="cell" lineBreakMode="truncatingTail" alignment="center" title="apple.com" id="o0g-Zv-pH4">
<font key="font" size="24" name="HelveticaNeue-Thin"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" name="alternateSelectedControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="xQb-o5-M5U" name="value" keyPath="objectValue.siteName" id="CZi-gD-5Ec">
<binding destination="xQb-o5-M5U" name="value" keyPath="objectValue.displayedName" id="CZi-gD-5Ec">
<dictionary key="options">
<bool key="NSContinuouslyUpdatesValue" value="YES"/>
</dictionary>
@@ -195,11 +200,10 @@
<constraint firstItem="ydd-Rv-tra" firstAttribute="top" secondItem="xQb-o5-M5U" secondAttribute="top" constant="2" id="eZT-Sd-wW5"/>
</constraints>
<backgroundFilters>
<ciFilter name="CIGloom">
<ciFilter name="CIGaussianBlur">
<configuration>
<null key="inputImage"/>
<real key="inputIntensity" value="1"/>
<real key="inputRadius" value="10"/>
<real key="inputRadius" value="20"/>
</configuration>
</ciFilter>
</backgroundFilters>
@@ -237,13 +241,13 @@
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OnR-s6-d4P" userLabel="Input Label">
<rect key="frame" x="209" y="310" width="223" height="20"/>
<shadow key="shadow" blurRadius="1">
<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>
<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"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
@@ -252,14 +256,14 @@
<constraints>
<constraint firstAttribute="width" constant="512" id="rW7-Vq-4Xy"/>
</constraints>
<shadow key="shadow" blurRadius="1">
<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" 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"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="calibratedRGB"/>
<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="NJO-iR-OXt"/>
@@ -268,10 +272,10 @@
</connections>
</searchField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vES-W5-m4x" userLabel="Type Button">
<rect key="frame" x="253" y="19" width="135" height="20"/>
<buttonCell key="cell" type="inline" title="Change Password Type" bezelStyle="inline" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Fom-sN-EtZ">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="11" name="HelveticaNeue-Bold"/>
<rect key="frame" x="242" y="19" width="157" height="19"/>
<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"/>
<font key="font" metaFont="systemBold" size="12"/>
<string key="keyEquivalent">t</string>
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell>
@@ -285,7 +289,7 @@
</connections>
</button>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="d3u-Ze-9uf" userLabel="Counter Container">
<rect key="frame" x="306" y="47" width="28" height="22"/>
<rect key="frame" x="306" y="46" width="28" height="22"/>
<subviews>
<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"/>
@@ -296,13 +300,13 @@
</stepper>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NvO-kt-eZ2" userLabel="Counter Field">
<rect key="frame" x="19" y="2" width="11" height="19"/>
<shadow key="shadow" blurRadius="1">
<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>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="1" id="dhQ-bJ-rn3">
<font key="font" size="12" name="HelveticaNeue-Medium"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
</textFieldCell>
<connections>
@@ -338,10 +342,10 @@
</connections>
</customView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1Qo-iG-CQt" userLabel="Login Button">
<rect key="frame" x="149" y="19" width="96" height="20"/>
<buttonCell key="cell" type="inline" title="Set Login Name" bezelStyle="inline" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="QFo-9y-aVe">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="11" name="HelveticaNeue-Bold"/>
<rect key="frame" x="123" y="19" width="111" height="19"/>
<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"/>
<font key="font" metaFont="systemBold" size="12"/>
<string key="keyEquivalent">l</string>
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell>
@@ -352,7 +356,7 @@
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="title" keyPath="selection.loginName" id="g1z-0F-hE9">
<binding destination="mcS-ik-b0n" name="title" keyPath="selection.loginName" id="uub-7k-XZ8">
<dictionary key="options">
<string key="NSNullPlaceholder">Set Login Name</string>
</dictionary>
@@ -363,10 +367,10 @@
<rect key="frame" x="312" y="524" width="16" height="16"/>
</progressIndicator>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XuF-Sp-6JD" userLabel="Delete Button">
<rect key="frame" x="396" y="19" width="70" height="20"/>
<buttonCell key="cell" type="inline" title="Delete Site" bezelStyle="inline" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="26m-of-YMQ">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="11" name="HelveticaNeue-Bold"/>
<rect key="frame" x="407" y="19" width="81" height="19"/>
<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"/>
<font key="font" metaFont="systemBold" size="12"/>
<string key="keyEquivalent">d</string>
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell>
@@ -380,10 +384,10 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="brI-fg-Kav" userLabel="Password Button">
<rect key="frame" x="266" y="46" width="108" height="20"/>
<buttonCell key="cell" type="inline" title="Change Password" bezelStyle="inline" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="FQu-fM-NWY">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="11" name="HelveticaNeue-Bold"/>
<rect key="frame" x="258" y="45" width="125" height="19"/>
<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"/>
<font key="font" metaFont="systemBold" size="12"/>
<string key="keyEquivalent">p</string>
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell>
@@ -410,7 +414,7 @@
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XUV-zU-Y9c">
<rect key="frame" x="298" y="41" width="4" height="97"/>
<shadow key="shadow" blurRadius="1">
<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>
@@ -418,8 +422,8 @@
<ciFilter name="CIGloom">
<configuration>
<null key="inputImage"/>
<real key="inputIntensity" value="1"/>
<real key="inputRadius" value="10"/>
<real key="inputIntensity" value="0.80000000000000004"/>
<real key="inputRadius" value="8"/>
</configuration>
</ciFilter>
</contentFilters>
@@ -434,18 +438,18 @@
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.contentDisplay" id="djg-i5-pwt"/>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.displayedContent" id="djg-i5-pwt"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ia6-7b-dFr">
<rect key="frame" x="114" y="82" width="372" height="14"/>
<shadow key="shadow" blurRadius="1">
<rect key="frame" x="111" y="82" width="378" height="14"/>
<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>
<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"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -475,16 +479,21 @@
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OaQ-of-zmb">
<rect key="frame" x="39" y="142" width="522" height="23"/>
<shadow key="shadow" blurRadius="1">
<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>
<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"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="hidden" keyPath="locked" id="I7S-x6-XZk">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="-2" name="hidden2" keyPath="newUser" previousBinding="I7S-x6-XZk" id="HKK-Eu-1qV">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
@@ -494,16 +503,11 @@
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="-2" name="hidden" keyPath="locked" id="I7S-x6-XZk">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="sYt-eL-uwt">
<rect key="frame" x="46" y="44" width="508" height="90"/>
<shadow key="shadow" blurRadius="1">
<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>
@@ -514,10 +518,15 @@
— Your "site name" can be any name; we recommend the bare domain name (eg. apple.com).
— Make your new master password strong (eg. a short sentence) and tell *nobody*.
— Share your site's password instead. You can change it if necessary.</string>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="-2" name="hidden" keyPath="locked" id="yDL-cR-bDf">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="-2" name="hidden2" keyPath="newUser" previousBinding="yDL-cR-bDf" id="fus-M7-S1J">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
@@ -527,11 +536,6 @@
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="-2" name="hidden" keyPath="locked" id="yDL-cR-bDf">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</textField>
</subviews>
@@ -546,15 +550,15 @@
<constraint firstAttribute="centerY" secondItem="sYt-eL-uwt" secondAttribute="centerY" id="zLS-QG-MKS"/>
</constraints>
</customView>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="npC-Kk-gUM">
<rect key="frame" x="140" y="235" width="359" height="15"/>
<shadow key="shadow" blurRadius="1">
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="npC-Kk-gUM">
<rect key="frame" x="101" y="235" width="438" height="15"/>
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.69999999999999996" colorSpace="calibratedWhite"/>
</shadow>
<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"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -571,13 +575,13 @@
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rhm-sC-xFS">
<rect key="frame" x="37" y="235" width="566" height="15"/>
<shadow key="shadow" blurRadius="1">
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.80000000000000004" colorSpace="calibratedWhite"/>
</shadow>
<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"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -595,13 +599,13 @@
</textField>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lW3-2z-cEa">
<rect key="frame" x="190" y="235" width="260" height="15"/>
<shadow key="shadow" blurRadius="1">
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.70000000000000007" colorSpace="calibratedWhite"/>
</shadow>
<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"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -612,7 +616,7 @@
</binding>
</connections>
</textField>
<button translatesAutoresizingMaskIntoConstraints="NO" id="Aue-Zx-6Mf">
<button translatesAutoresizingMaskIntoConstraints="NO" id="Aue-Zx-6Mf" userLabel="Settings Button">
<rect key="frame" x="588" y="508" width="32" height="32"/>
<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"/>
@@ -625,14 +629,14 @@
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="qal-PP-YtO">
<rect key="frame" x="420" y="1" width="23" height="15"/>
<shadow key="shadow" blurRadius="1">
<rect key="frame" x="436" y="1" width="23" height="15"/>
<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>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘D" id="PPC-be-w4E">
<font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -654,13 +658,13 @@
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9b3-wy-KBb">
<rect key="frame" x="309" y="2" width="22" height="14"/>
<shadow key="shadow" blurRadius="1">
<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>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘T" id="HFM-Bk-akx">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -681,14 +685,14 @@
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ido-NQ-3MY">
<rect key="frame" x="186" y="1" width="22" height="15"/>
<shadow key="shadow" blurRadius="1">
<rect key="frame" x="167" y="1" width="22" height="15"/>
<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>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘L" id="fUB-rF-7x8">
<font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -709,14 +713,14 @@
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="uol-dE-I8H">
<rect key="frame" x="309" y="70" width="22" height="14"/>
<shadow key="shadow" blurRadius="1">
<rect key="frame" x="309" y="68" width="23" height="14"/>
<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>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘P" id="MyN-x6-dMk">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -746,14 +750,14 @@
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="UpZ-rb-NXd">
<rect key="frame" x="242" y="70" width="157" height="14"/>
<shadow key="shadow" blurRadius="1">
<rect key="frame" x="241" y="68" width="158" height="14"/>
<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>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Click here to set a password:" id="gjc-Fw-xa1">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -788,13 +792,13 @@
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gAU-xs-aae">
<rect key="frame" x="595" y="490" width="19" height="14"/>
<shadow key="shadow" blurRadius="1">
<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>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘," id="Xm1-qb-6EP">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="highlightColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -810,7 +814,7 @@
<constraint firstItem="v80-wd-hUR" firstAttribute="top" secondItem="iGR-wo-ual" secondAttribute="top" id="1iV-OU-5Ay"/>
<constraint firstItem="brI-fg-Kav" firstAttribute="centerX" secondItem="vES-W5-m4x" secondAttribute="centerX" id="1tN-p4-2m4"/>
<constraint firstItem="Ido-NQ-3MY" firstAttribute="top" secondItem="1Qo-iG-CQt" secondAttribute="bottom" constant="4" id="3MM-M7-OKF"/>
<constraint firstAttribute="bottom" secondItem="Bwc-sd-6gm" secondAttribute="bottom" id="3fF-7g-c6C"/>
<constraint firstAttribute="bottom" secondItem="Bwc-sd-6gm" secondAttribute="bottom" constant="-80" id="3fF-7g-c6C"/>
<constraint firstItem="XuF-Sp-6JD" firstAttribute="centerX" secondItem="qal-PP-YtO" secondAttribute="centerX" id="7mj-3B-j0X"/>
<constraint firstItem="NGk-Io-Buc" firstAttribute="top" secondItem="oSh-Ec-8Nf" secondAttribute="bottom" constant="8" symbolic="YES" id="8AC-MT-cz4"/>
<constraint firstItem="vES-W5-m4x" firstAttribute="centerX" secondItem="CnS-iI-dhr" secondAttribute="centerX" id="92S-HP-Vk7"/>
@@ -822,7 +826,7 @@
<constraint firstAttribute="centerY" secondItem="iGR-wo-ual" secondAttribute="centerY" id="GZE-mX-kjj"/>
<constraint firstAttribute="centerY" secondItem="CnS-iI-dhr" secondAttribute="centerY" id="HjG-vb-3Qg"/>
<constraint firstItem="iGR-wo-ual" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="20" symbolic="YES" id="KNz-B2-qfi"/>
<constraint firstItem="Bwc-sd-6gm" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="Kqb-ig-5cP"/>
<constraint firstItem="Bwc-sd-6gm" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="-80" id="Kqb-ig-5cP"/>
<constraint firstAttribute="trailing" secondItem="iGR-wo-ual" secondAttribute="trailing" constant="20" symbolic="YES" id="LW8-vu-scs"/>
<constraint firstItem="Aue-Zx-6Mf" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" constant="20" symbolic="YES" id="Lts-go-pIX"/>
<constraint firstAttribute="bottom" secondItem="Bme-XK-MMc" secondAttribute="bottom" constant="80" id="MbE-Oa-J9k"/>
@@ -845,7 +849,7 @@
<constraint firstItem="OnR-s6-d4P" firstAttribute="top" secondItem="NGk-Io-Buc" secondAttribute="bottom" constant="8" symbolic="YES" id="dr2-eR-Yup"/>
<constraint firstAttribute="bottom" secondItem="vES-W5-m4x" secondAttribute="bottom" constant="20" symbolic="YES" id="eHI-Tn-bYD"/>
<constraint firstItem="rhm-sC-xFS" firstAttribute="top" secondItem="CnS-iI-dhr" secondAttribute="bottom" constant="8" symbolic="YES" id="f1g-ug-BVL"/>
<constraint firstAttribute="trailing" secondItem="Bwc-sd-6gm" secondAttribute="trailing" id="gKu-JH-NDR"/>
<constraint firstAttribute="trailing" secondItem="Bwc-sd-6gm" secondAttribute="trailing" constant="-80" id="gKu-JH-NDR"/>
<constraint firstItem="CnS-iI-dhr" firstAttribute="centerX" secondItem="rhm-sC-xFS" secondAttribute="centerX" id="gmg-aZ-1Si"/>
<constraint firstItem="Bme-XK-MMc" firstAttribute="top" secondItem="rhm-sC-xFS" secondAttribute="bottom" constant="8" symbolic="YES" id="gsL-Ww-yLa"/>
<constraint firstItem="9b3-wy-KBb" firstAttribute="top" secondItem="vES-W5-m4x" secondAttribute="bottom" constant="4" id="hKa-2u-uL3"/>
@@ -858,7 +862,7 @@
<constraint firstItem="vES-W5-m4x" firstAttribute="top" secondItem="brI-fg-Kav" secondAttribute="bottom" constant="8" symbolic="YES" id="rCP-oh-rWr"/>
<constraint firstItem="v80-wd-hUR" firstAttribute="trailing" secondItem="iGR-wo-ual" secondAttribute="trailing" id="rIx-cQ-PNt"/>
<constraint firstItem="brI-fg-Kav" firstAttribute="centerX" secondItem="uol-dE-I8H" secondAttribute="centerX" id="s5w-Nc-YJY"/>
<constraint firstItem="Bwc-sd-6gm" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="tea-fv-b1S"/>
<constraint firstItem="Bwc-sd-6gm" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" constant="-80" id="tea-fv-b1S"/>
<constraint firstItem="lW3-2z-cEa" firstAttribute="centerX" secondItem="iGR-wo-ual" secondAttribute="centerX" id="vML-2u-shw"/>
<constraint firstItem="v80-wd-hUR" firstAttribute="bottom" secondItem="iGR-wo-ual" secondAttribute="bottom" id="xiX-8e-pNR"/>
<constraint firstItem="v80-wd-hUR" firstAttribute="leading" secondItem="iGR-wo-ual" secondAttribute="leading" id="yVZ-Ar-5ov"/>
@@ -867,6 +871,7 @@
</constraints>
<animations/>
</view>
<point key="canvasLocation" x="-267" y="279"/>
</window>
<userDefaultsController representsSharedInstance="YES" id="yy2-3W-Ocj"/>
<arrayController objectClassName="MPSiteModel" id="mcS-ik-b0n">

View File

@@ -17,15 +17,17 @@
//
#import <Foundation/Foundation.h>
#import "MPSiteEntity.h"
@class MPSiteEntity;
@interface MPSiteModel : NSObject
@property (nonatomic) NSString *siteName;
@property (nonatomic) NSString *name;
@property (nonatomic) NSAttributedString *displayedName;
@property (nonatomic) MPSiteType type;
@property (nonatomic) NSString *typeName;
@property (nonatomic) NSString *content;
@property (nonatomic) NSString *contentDisplay;
@property (nonatomic) NSString *displayedContent;
@property (nonatomic) NSString *loginName;
@property (nonatomic) NSNumber *uses;
@property (nonatomic) NSUInteger counter;
@@ -34,7 +36,7 @@
@property (nonatomic) BOOL generated;
@property (nonatomic) BOOL stored;
- (id)initWithEntity:(MPSiteEntity *)entity;
- (instancetype)initWithEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups;
- (MPSiteEntity *)entityInContext:(NSManagedObjectContext *)moc;
- (void)updateContent;

View File

@@ -28,27 +28,42 @@
BOOL _initialized;
}
- (id)initWithEntity:(MPSiteEntity *)entity {
- (id)initWithEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups {
if (!(self = [super init]))
return nil;
[self setEntity:entity];
[self setEntity:entity fuzzyGroups:fuzzyGroups];
_initialized = YES;
return self;
}
- (void)setEntity:(MPSiteEntity *)entity {
- (void)setEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups {
if ([_entityOID isEqual:entity.objectID])
return;
_entityOID = entity.objectID;
NSString *siteName = entity.name;
NSMutableAttributedString *attributedSiteName = [[NSMutableAttributedString alloc] initWithString:siteName];
for (NSUInteger f = 0, s = (NSUInteger)-1; f < [fuzzyGroups count]; ++f) {
s = [siteName rangeOfString:fuzzyGroups[f] options:NSDiacriticInsensitiveSearch | NSCaseInsensitiveSearch
range:NSMakeRange( s + 1, [siteName length] - (s + 1) )].location;
if (s == NSNotFound)
break;
[attributedSiteName addAttribute:NSBackgroundColorAttributeName value:[NSColor alternateSelectedControlColor]
range:NSMakeRange( s, [fuzzyGroups[f] length] )];
}
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.alignment = NSCenterTextAlignment;
[attributedSiteName addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange( 0, [siteName length] )];
self.displayedName = attributedSiteName;
self.name = siteName;
self.algorithm = entity.algorithm;
self.siteName = entity.name;
self.lastUsed = entity.lastUsed;
self.loginName = entity.loginName;
self.type = entity.type;
self.typeName = entity.typeName;
self.uses = entity.uses_;
@@ -124,7 +139,12 @@
PearlMainQueue( ^{
self.content = result;
self.contentDisplay = displayResult;
self.displayedContent = displayResult;
} );
}];
[entity resolveLoginUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
PearlMainQueue( ^{
self.loginName = result;
} );
}];
}

View File

@@ -39,8 +39,6 @@
</array>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>MasterPassword</string>
<key>CFBundleIdentifier</key>
<string>com.lyndir.lhunath.MasterPassword.Mac</string>
<key>CFBundleInfoDictionaryVersion</key>
@@ -62,7 +60,7 @@
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2011-2013 Lyndir. All rights reserved.</string>
<string>Copyright © 2011-2014 Lyndir</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>

View File

@@ -103,7 +103,7 @@
isa = PBXProject;
attributes = {
CLASSPREFIX = MP;
LastUpgradeCheck = 0510;
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = "Maarten Billemont";
TargetAttributes = {
DAD9B5C0176299B9001835F9 = {
@@ -209,6 +209,7 @@
CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application";
COMBINE_HIDPI_IMAGES = YES;
INFOPLIST_FILE = "$(SRCROOT)/MasterPassword-Mac-LoginHelper/MasterPassword-Mac-LoginHelper-Info.plist";
PROVISIONING_PROFILE = "8ea8f441-a2d3-4119-ad85-f18953e17648";
};
name = "AppStore-Mac";
};

View File

@@ -10,6 +10,7 @@
93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D9D0061FF1159998F06 /* MPPasswordWindow.m */; };
93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; };
93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */; };
93D395E4830290EBB6E71F34 /* MPNoStateButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39538C4CEFF46DF379254 /* MPNoStateButton.m */; };
93D395F08A087F8A24689347 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */; };
93D3970BCF85F7902E611168 /* PearlProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DB3A8ADED08C39A6228 /* PearlProfiler.m */; };
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */; };
@@ -22,13 +23,11 @@
DA0933D01747B91B00DE1CEF /* appstore.png in Resources */ = {isa = PBXBuildFile; fileRef = DA0933CF1747B91B00DE1CEF /* appstore.png */; };
DA10007F1998A4C6002B873F /* scrypt in Headers */ = {isa = PBXBuildFile; fileRef = DAE8E65619867AF500416A0F /* scrypt */; settings = {ATTRIBUTES = (Public, ); }; };
DA1000801998A4C6002B873F /* openssl in Headers */ = {isa = PBXBuildFile; fileRef = DAE8E65719867AF500416A0F /* openssl */; settings = {ATTRIBUTES = (Public, ); }; };
DA16B33F170661D4000A0EAB /* libUbiquityStoreManager.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA4425CB1557BED40052177D /* libUbiquityStoreManager.a */; };
DA16B341170661DB000A0EAB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA16B340170661DB000A0EAB /* Carbon.framework */; };
DA16B342170661E0000A0EAB /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC632871486D95D0075AEA5 /* Security.framework */; };
DA16B344170661EE000A0EAB /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA16B343170661EE000A0EAB /* Cocoa.framework */; };
DA16B345170661F2000A0EAB /* libPearl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC77CAD148291A600BCF976 /* libPearl.a */; };
DA2508F119511D3600AC23F1 /* MPPasswordWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = DA2508F019511D3600AC23F1 /* MPPasswordWindowController.xib */; };
DA2508F719513C1400AC23F1 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA16B343170661EE000A0EAB /* Cocoa.framework */; };
DA250925195148E200AC23F1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAEBC45214F6364500987BF6 /* QuartzCore.framework */; };
DA29992C19C6A89900AF7DF1 /* MasterPassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA29992619C6A89900AF7DF1 /* MasterPassword.xcdatamodeld */; };
DA2CA4ED18D323D3007798F8 /* NSError+PearlFullDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2CA4E718D323D3007798F8 /* NSError+PearlFullDescription.m */; };
@@ -55,15 +54,15 @@
DA3B8453190FC86F00246EEA /* NSManagedObject+Pearl.h in Headers */ = {isa = PBXBuildFile; fileRef = DA3B8451190FC86F00246EEA /* NSManagedObject+Pearl.h */; };
DA3B8456190FC89700246EEA /* MPFixable.m in Sources */ = {isa = PBXBuildFile; fileRef = DA3B8454190FC89700246EEA /* MPFixable.m */; };
DA3BCFCD19BD09E0006B2681 /* SourceCodePro-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = DA3BCFCC19BD09E0006B2681 /* SourceCodePro-Regular.otf */; };
DA4425CC1557BED40052177D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DA4DA1D91564471A00F6F596 /* libjrswizzle.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC6326C148680650075AEA5 /* libjrswizzle.a */; };
DA5180CA19FF2F9200A587E9 /* MPAlgorithmV2.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5180C719FF2F9200A587E9 /* MPAlgorithmV2.m */; };
DA5180CE19FF307E00A587E9 /* MPAppDelegate_Store.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5180CD19FF307E00A587E9 /* MPAppDelegate_Store.m */; };
DA5E5C9417248AA1003798D8 /* libscryptenc-osx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5E5C8717248AA1003798D8 /* libscryptenc-osx.a */; };
DA5E5CF61724A667003798D8 /* MPAlgorithm.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5C981724A667003798D8 /* MPAlgorithm.m */; };
DA5E5CF71724A667003798D8 /* MPAlgorithmV0.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5C9A1724A667003798D8 /* MPAlgorithmV0.m */; };
DA5E5CF81724A667003798D8 /* MPAlgorithmV1.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5C9C1724A667003798D8 /* MPAlgorithmV1.m */; };
DA5E5CF91724A667003798D8 /* MPAppDelegate_Key.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5C9E1724A667003798D8 /* MPAppDelegate_Key.m */; };
DA5E5CFA1724A667003798D8 /* MPAppDelegate_Shared.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA01724A667003798D8 /* MPAppDelegate_Shared.m */; };
DA5E5CFB1724A667003798D8 /* MPAppDelegate_Store.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */; };
DA5E5CFC1724A667003798D8 /* MPConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA41724A667003798D8 /* MPConfig.m */; };
DA5E5D001724A667003798D8 /* MPEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CAC1724A667003798D8 /* MPEntities.m */; };
DA5E5D011724A667003798D8 /* MPKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CAE1724A667003798D8 /* MPKey.m */; };
@@ -80,15 +79,14 @@
DA8ED896192906920099B726 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8ED892192906920099B726 /* PearlTween.h */; };
DA8ED897192906920099B726 /* map-macro.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8ED894192906920099B726 /* map-macro.h */; };
DAAA81B0195A8D1300FA30D9 /* gradient.png in Resources */ = {isa = PBXBuildFile; fileRef = DAAA81AF195A8D1300FA30D9 /* gradient.png */; };
DABC6C02175D8C85000C15D4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DABC6C15175D8CE1000C15D4 /* RHStatusItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = DABC6C14175D8CE1000C15D4 /* RHStatusItemView.m */; };
DABC6C16175D8E3A000C15D4 /* libRHStatusItemView.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DABC6C01175D8C85000C15D4 /* libRHStatusItemView.a */; };
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 */; };
DAADCC4919FAFFAD00987B1D /* NSPersistentStore+PearlMigration.m in Sources */ = {isa = PBXBuildFile; fileRef = DAADCC4019FAFFAD00987B1D /* NSPersistentStore+PearlMigration.m */; };
DAADCC4B19FB000C00987B1D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAEBC45214F6364500987BF6 /* QuartzCore.framework */; };
DAADCC6919FB007F00987B1D /* NSManagedObjectModel+KCOrderedAccessorFix.m in Sources */ = {isa = PBXBuildFile; fileRef = DAADCC6719FB007F00987B1D /* NSManagedObjectModel+KCOrderedAccessorFix.m */; };
DAADCC6A19FB00B500987B1D /* libKCOrderedAccessorFix.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAADCC5019FB006500987B1D /* libKCOrderedAccessorFix.a */; };
DAC6326D148680650075AEA5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DAC77CAE148291A600BCF976 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DACA22BB1705DE7D002C6C22 /* UbiquityStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DACA22B71705DE7D002C6C22 /* UbiquityStoreManager.m */; };
DACA22BC1705DE7D002C6C22 /* NSError+UbiquityStoreManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA22B81705DE7D002C6C22 /* NSError+UbiquityStoreManager.h */; };
DACA22BD1705DE7D002C6C22 /* NSError+UbiquityStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DACA22B91705DE7D002C6C22 /* NSError+UbiquityStoreManager.m */; };
DACA22BE1705DE7D002C6C22 /* UbiquityStoreManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA22BA1705DE7D002C6C22 /* UbiquityStoreManager.h */; };
DACA26FE1705DF81002C6C22 /* logo-bare.png in Resources */ = {isa = PBXBuildFile; fileRef = DACA241C1705DF7D002C6C22 /* logo-bare.png */; };
DACA27121705DF81002C6C22 /* avatar-13@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DACA24321705DF7D002C6C22 /* avatar-13@2x.png */; };
DACA27131705DF81002C6C22 /* avatar-3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DACA24331705DF7D002C6C22 /* avatar-3@2x.png */; };
@@ -213,6 +211,15 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
DAADCC4E19FB006500987B1D /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
DAD9B5EE1762CA3A001835F9 /* Copy LoginHelper */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@@ -229,11 +236,13 @@
/* Begin PBXFileReference section */
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
93D39240B5143E01F0B75E96 /* MPSiteModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteModel.h; sourceTree = "<group>"; };
93D392A4F3DE0BD758B9B056 /* MPNoStateButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPNoStateButton.h; sourceTree = "<group>"; };
93D392C3918763B3B72CF366 /* MPPasswordWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindowController.h; sourceTree = "<group>"; };
93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPInitialWindowController.h; sourceTree = "<group>"; };
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = "<group>"; };
93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSitesTableView.m; sourceTree = "<group>"; };
93D394EEFF5BF555A55AF361 /* PearlProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PearlProfiler.h; path = ../../../External/Pearl/Pearl/PearlProfiler.h; sourceTree = "<group>"; };
93D39538C4CEFF46DF379254 /* MPNoStateButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPNoStateButton.m; sourceTree = "<group>"; };
93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = "<group>"; };
93D3977484534E99F9BA579D /* MPPasswordWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindow.h; sourceTree = "<group>"; };
93D39A57A7823DE98A0FF83C /* MPPasswordWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordWindowController.m; sourceTree = "<group>"; };
@@ -249,7 +258,6 @@
DA16B340170661DB000A0EAB /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
DA16B343170661EE000A0EAB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
DA2508F019511D3600AC23F1 /* MPPasswordWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MPPasswordWindowController.xib; sourceTree = "<group>"; };
DA2508F619513C1400AC23F1 /* libRMBlurredView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRMBlurredView.a; sourceTree = BUILT_PRODUCTS_DIR; };
DA2508F919513C1400AC23F1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
DA2508FA19513C1400AC23F1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
DA2508FB19513C1400AC23F1 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
@@ -292,7 +300,10 @@
DA3B8454190FC89700246EEA /* MPFixable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPFixable.m; sourceTree = "<group>"; };
DA3B8455190FC89700246EEA /* MPFixable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPFixable.h; sourceTree = "<group>"; };
DA3BCFCC19BD09E0006B2681 /* SourceCodePro-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SourceCodePro-Regular.otf"; sourceTree = "<group>"; };
DA4425CB1557BED40052177D /* libUbiquityStoreManager.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libUbiquityStoreManager.a; sourceTree = BUILT_PRODUCTS_DIR; };
DA5180C619FF2F9200A587E9 /* MPAlgorithmV2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAlgorithmV2.h; sourceTree = "<group>"; };
DA5180C719FF2F9200A587E9 /* MPAlgorithmV2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAlgorithmV2.m; sourceTree = "<group>"; };
DA5180CC19FF307E00A587E9 /* MPAppDelegate_Store.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_Store.h; sourceTree = "<group>"; };
DA5180CD19FF307E00A587E9 /* MPAppDelegate_Store.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Store.m; sourceTree = "<group>"; };
DA5BFA44147E415C00F98B1E /* Master Password.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Master Password.app"; sourceTree = BUILT_PRODUCTS_DIR; };
DA5BFA4A147E415C00F98B1E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
DA5BFA4C147E415C00F98B1E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
@@ -308,8 +319,6 @@
DA5E5C9E1724A667003798D8 /* MPAppDelegate_Key.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Key.m; sourceTree = "<group>"; };
DA5E5C9F1724A667003798D8 /* MPAppDelegate_Shared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_Shared.h; sourceTree = "<group>"; };
DA5E5CA01724A667003798D8 /* MPAppDelegate_Shared.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Shared.m; sourceTree = "<group>"; };
DA5E5CA11724A667003798D8 /* MPAppDelegate_Store.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_Store.h; sourceTree = "<group>"; };
DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Store.m; sourceTree = "<group>"; };
DA5E5CA31724A667003798D8 /* MPConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPConfig.h; sourceTree = "<group>"; };
DA5E5CA41724A667003798D8 /* MPConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPConfig.m; sourceTree = "<group>"; };
DA5E5CAB1724A667003798D8 /* MPEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntities.h; sourceTree = "<group>"; };
@@ -737,18 +746,17 @@
DA8ED892192906920099B726 /* PearlTween.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlTween.h; sourceTree = "<group>"; };
DA8ED894192906920099B726 /* map-macro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "map-macro.h"; 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>"; };
DAADCC3F19FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+PearlMigration.h"; sourceTree = "<group>"; };
DAADCC4019FAFFAD00987B1D /* NSPersistentStore+PearlMigration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStore+PearlMigration.m"; sourceTree = "<group>"; };
DAADCC5019FB006500987B1D /* libKCOrderedAccessorFix.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libKCOrderedAccessorFix.a; sourceTree = BUILT_PRODUCTS_DIR; };
DAADCC6619FB007F00987B1D /* NSManagedObjectModel+KCOrderedAccessorFix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSManagedObjectModel+KCOrderedAccessorFix.h"; sourceTree = "<group>"; };
DAADCC6719FB007F00987B1D /* NSManagedObjectModel+KCOrderedAccessorFix.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSManagedObjectModel+KCOrderedAccessorFix.m"; sourceTree = "<group>"; };
DABB981515100B4000B05417 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
DABC6C01175D8C85000C15D4 /* libRHStatusItemView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRHStatusItemView.a; sourceTree = BUILT_PRODUCTS_DIR; };
DABC6C13175D8CE1000C15D4 /* RHStatusItemView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RHStatusItemView.h; sourceTree = "<group>"; };
DABC6C14175D8CE1000C15D4 /* RHStatusItemView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RHStatusItemView.m; sourceTree = "<group>"; };
DAC6326C148680650075AEA5 /* libjrswizzle.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjrswizzle.a; sourceTree = BUILT_PRODUCTS_DIR; };
DAC632871486D95D0075AEA5 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
DAC77CAD148291A600BCF976 /* libPearl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPearl.a; sourceTree = BUILT_PRODUCTS_DIR; };
DAC77CB1148291A600BCF976 /* Pearl-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Pearl-Prefix.pch"; path = "../../MasterPassword/ObjC/Pearl/Pearl-Prefix.pch"; sourceTree = "<group>"; };
DACA22B71705DE7D002C6C22 /* UbiquityStoreManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UbiquityStoreManager.m; sourceTree = "<group>"; };
DACA22B81705DE7D002C6C22 /* NSError+UbiquityStoreManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+UbiquityStoreManager.h"; sourceTree = "<group>"; };
DACA22B91705DE7D002C6C22 /* NSError+UbiquityStoreManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSError+UbiquityStoreManager.m"; sourceTree = "<group>"; };
DACA22BA1705DE7D002C6C22 /* UbiquityStoreManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UbiquityStoreManager.h; sourceTree = "<group>"; };
DACA241C1705DF7D002C6C22 /* logo-bare.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "logo-bare.png"; sourceTree = "<group>"; };
DACA24321705DF7D002C6C22 /* avatar-13@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-13@2x.png"; sourceTree = "<group>"; };
DACA24331705DF7D002C6C22 /* avatar-3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-3@2x.png"; sourceTree = "<group>"; };
@@ -796,6 +804,17 @@
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>"; };
DACA298C1705E2BD002C6C22 /* JRSwizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JRSwizzle.m; 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>"; };
DAD0C5F819FD6034009CB08D /* icon_16x16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_16x16.png; sourceTree = "<group>"; };
DAD0C5F919FD6034009CB08D /* icon_16x16@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_16x16@2x.png"; sourceTree = "<group>"; };
DAD0C5FA19FD6034009CB08D /* icon_256x256.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_256x256.png; sourceTree = "<group>"; };
DAD0C5FB19FD6034009CB08D /* icon_256x256@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_256x256@2x.png"; sourceTree = "<group>"; };
DAD0C5FC19FD6034009CB08D /* icon_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_32x32.png; sourceTree = "<group>"; };
DAD0C5FD19FD6034009CB08D /* icon_32x32@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_32x32@2x.png"; sourceTree = "<group>"; };
DAD0C5FE19FD6034009CB08D /* icon_512x512.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_512x512.png; sourceTree = "<group>"; };
DAD0C5FF19FD6034009CB08D /* icon_512x512@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_512x512@2x.png"; sourceTree = "<group>"; };
DAD0C60019FD6034009CB08D /* icon.sketch */ = {isa = PBXFileReference; lastKnownFileType = file; path = icon.sketch; sourceTree = "<group>"; };
DAD312C01552A20800A3F9ED /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; };
DAD9B5E1176299B9001835F9 /* MasterPassword-Mac-LoginHelper.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "MasterPassword-Mac-LoginHelper.xcodeproj"; path = "MasterPassword-Mac-LoginHelper/MasterPassword-Mac-LoginHelper.xcodeproj"; sourceTree = "<group>"; };
DAD9B5EF1762CAA4001835F9 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };
@@ -854,30 +873,13 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
DA2508F319513C1400AC23F1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DA2508F719513C1400AC23F1 /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DA4425C81557BED40052177D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DA4425CC1557BED40052177D /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DA5BFA41147E415C00F98B1E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DAADCC6A19FB00B500987B1D /* libKCOrderedAccessorFix.a in Frameworks */,
DA250925195148E200AC23F1 /* QuartzCore.framework in Frameworks */,
DAD9B5F01762CAA4001835F9 /* ServiceManagement.framework in Frameworks */,
DABC6C16175D8E3A000C15D4 /* libRHStatusItemView.a in Frameworks */,
DA16B33F170661D4000A0EAB /* libUbiquityStoreManager.a in Frameworks */,
DA16B341170661DB000A0EAB /* Carbon.framework in Frameworks */,
DA16B342170661E0000A0EAB /* Security.framework in Frameworks */,
DA16B345170661F2000A0EAB /* libPearl.a in Frameworks */,
@@ -886,11 +888,10 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DABC6BFE175D8C85000C15D4 /* Frameworks */ = {
DAADCC4D19FB006500987B1D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DABC6C02175D8C85000C15D4 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -906,6 +907,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DAADCC4B19FB000C00987B1D /* QuartzCore.framework in Frameworks */,
DAE8E65519867AE200416A0F /* libopensslcrypto-osx.a in Frameworks */,
DA4DA1D91564471A00F6F596 /* libjrswizzle.a in Frameworks */,
DAC77CAE148291A600BCF976 /* Foundation.framework in Frameworks */,
@@ -953,9 +955,7 @@
DA5BFA44147E415C00F98B1E /* Master Password.app */,
DAC77CAD148291A600BCF976 /* libPearl.a */,
DAC6326C148680650075AEA5 /* libjrswizzle.a */,
DA4425CB1557BED40052177D /* libUbiquityStoreManager.a */,
DABC6C01175D8C85000C15D4 /* libRHStatusItemView.a */,
DA2508F619513C1400AC23F1 /* libRMBlurredView.a */,
DAADCC5019FB006500987B1D /* libKCOrderedAccessorFix.a */,
);
name = Products;
sourceTree = "<group>";
@@ -995,39 +995,41 @@
DA5E5C961724A667003798D8 /* ObjC */ = {
isa = PBXGroup;
children = (
DA32CFE319CF1C71004F3F0E /* MPUserEntity.h */,
DA32CFE419CF1C71004F3F0E /* MPUserEntity.m */,
DA32CFE019CF1C71004F3F0E /* MPSiteQuestionEntity.h */,
DA32CFE119CF1C71004F3F0E /* MPSiteQuestionEntity.m */,
DA32CFDD19CF1C70004F3F0E /* MPSiteEntity.h */,
DA32CFDE19CF1C70004F3F0E /* MPSiteEntity.m */,
DA32CFDA19CF1C70004F3F0E /* MPStoredSiteEntity.h */,
DA32CFDB19CF1C70004F3F0E /* MPStoredSiteEntity.m */,
DA32CFD719CF1C70004F3F0E /* MPGeneratedSiteEntity.h */,
DA32CFD819CF1C70004F3F0E /* MPGeneratedSiteEntity.m */,
DA3B8454190FC89700246EEA /* MPFixable.m */,
DA3B8455190FC89700246EEA /* MPFixable.h */,
DA5E5CB21724A667003798D8 /* Mac */,
DA29992619C6A89900AF7DF1 /* MasterPassword.xcdatamodeld */,
DA5E5C971724A667003798D8 /* MPAlgorithm.h */,
DA5E5C981724A667003798D8 /* MPAlgorithm.m */,
DA5E5C991724A667003798D8 /* MPAlgorithmV0.h */,
DA5E5C9A1724A667003798D8 /* MPAlgorithmV0.m */,
DA5E5C9B1724A667003798D8 /* MPAlgorithmV1.h */,
DA5E5C9C1724A667003798D8 /* MPAlgorithmV1.m */,
DA5180C619FF2F9200A587E9 /* MPAlgorithmV2.h */,
DA5180C719FF2F9200A587E9 /* MPAlgorithmV2.m */,
DA5E5C9D1724A667003798D8 /* MPAppDelegate_Key.h */,
DA5E5C9E1724A667003798D8 /* MPAppDelegate_Key.m */,
DA5E5C9F1724A667003798D8 /* MPAppDelegate_Shared.h */,
DA5E5CA01724A667003798D8 /* MPAppDelegate_Shared.m */,
DA5E5CA11724A667003798D8 /* MPAppDelegate_Store.h */,
DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */,
DA5180CC19FF307E00A587E9 /* MPAppDelegate_Store.h */,
DA5180CD19FF307E00A587E9 /* MPAppDelegate_Store.m */,
DA5E5CA31724A667003798D8 /* MPConfig.h */,
DA5E5CA41724A667003798D8 /* MPConfig.m */,
DA5E5CAB1724A667003798D8 /* MPEntities.h */,
DA5E5CAC1724A667003798D8 /* MPEntities.m */,
DA3B8455190FC89700246EEA /* MPFixable.h */,
DA3B8454190FC89700246EEA /* MPFixable.m */,
DA32CFD719CF1C70004F3F0E /* MPGeneratedSiteEntity.h */,
DA32CFD819CF1C70004F3F0E /* MPGeneratedSiteEntity.m */,
DA5E5CAD1724A667003798D8 /* MPKey.h */,
DA5E5CAE1724A667003798D8 /* MPKey.m */,
DA32CFDD19CF1C70004F3F0E /* MPSiteEntity.h */,
DA32CFDE19CF1C70004F3F0E /* MPSiteEntity.m */,
DA32CFE019CF1C71004F3F0E /* MPSiteQuestionEntity.h */,
DA32CFE119CF1C71004F3F0E /* MPSiteQuestionEntity.m */,
DA32CFDA19CF1C70004F3F0E /* MPStoredSiteEntity.h */,
DA32CFDB19CF1C70004F3F0E /* MPStoredSiteEntity.m */,
DA5E5CAF1724A667003798D8 /* MPTypes.h */,
DA29992619C6A89900AF7DF1 /* MasterPassword.xcdatamodeld */,
DA32CFE319CF1C71004F3F0E /* MPUserEntity.h */,
DA32CFE419CF1C71004F3F0E /* MPUserEntity.m */,
);
name = ObjC;
path = ..;
@@ -1059,6 +1061,8 @@
93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */,
93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */,
93D39AC6360DDC16AEAA4119 /* MPSitesTableView.h */,
93D39538C4CEFF46DF379254 /* MPNoStateButton.m */,
93D392A4F3DE0BD758B9B056 /* MPNoStateButton.h */,
);
path = Mac;
sourceTree = "<group>";
@@ -1480,14 +1484,13 @@
path = include;
sourceTree = "<group>";
};
DABC6C0E175D8CE1000C15D4 /* RHStatusItemView */ = {
DAADCC6819FB007F00987B1D /* KCOrderedAccessorFix */ = {
isa = PBXGroup;
children = (
DABC6C13175D8CE1000C15D4 /* RHStatusItemView.h */,
DABC6C14175D8CE1000C15D4 /* RHStatusItemView.m */,
DAADCC6619FB007F00987B1D /* NSManagedObjectModel+KCOrderedAccessorFix.h */,
DAADCC6719FB007F00987B1D /* NSManagedObjectModel+KCOrderedAccessorFix.m */,
);
name = RHStatusItemView;
path = RHStatusItemView/RHStatusItemView;
path = KCOrderedAccessorFix;
sourceTree = "<group>";
};
DAC77CAF148291A600BCF976 /* Pearl */ = {
@@ -1503,28 +1506,15 @@
DACA22121705DDC5002C6C22 /* External */ = {
isa = PBXGroup;
children = (
DAADCC6819FB007F00987B1D /* KCOrderedAccessorFix */,
DA3B8449190FC5A900246EEA /* Mac */,
DABC6C0E175D8CE1000C15D4 /* RHStatusItemView */,
DACA29751705E2BD002C6C22 /* jrswizzle */,
DAC77CAF148291A600BCF976 /* Pearl */,
DACA22B61705DE7D002C6C22 /* UbiquityStoreManager */,
);
name = External;
path = ../../../External;
sourceTree = "<group>";
};
DACA22B61705DE7D002C6C22 /* UbiquityStoreManager */ = {
isa = PBXGroup;
children = (
DACA22BA1705DE7D002C6C22 /* UbiquityStoreManager.h */,
DACA22B71705DE7D002C6C22 /* UbiquityStoreManager.m */,
DACA22B81705DE7D002C6C22 /* NSError+UbiquityStoreManager.h */,
DACA22B91705DE7D002C6C22 /* NSError+UbiquityStoreManager.m */,
);
name = UbiquityStoreManager;
path = UbiquityStoreManager/UbiquityStoreManager;
sourceTree = "<group>";
};
DACA23B41705DF7D002C6C22 /* Resources */ = {
isa = PBXGroup;
children = (
@@ -1539,6 +1529,7 @@
DACA23B51705DF7D002C6C22 /* Media */ = {
isa = PBXGroup;
children = (
DAD0C5F419FD6034009CB08D /* mac */,
DA6558A319A99609009A0BEB /* Images.xcassets */,
DA606FE9195D03E200CA98B5 /* Insignia */,
DAAA81AF195A8D1300FA30D9 /* gradient.png */,
@@ -1636,8 +1627,33 @@
DACA29771705E2BD002C6C22 /* JRSwizzle.h */,
DACA298C1705E2BD002C6C22 /* JRSwizzle.m */,
);
name = jrswizzle;
path = Pearl/External/jrswizzle;
path = jrswizzle;
sourceTree = "<group>";
};
DAD0C5F419FD6034009CB08D /* mac */ = {
isa = PBXGroup;
children = (
DAD0C5F519FD6034009CB08D /* icon */,
DAD0C60019FD6034009CB08D /* icon.sketch */,
);
path = mac;
sourceTree = "<group>";
};
DAD0C5F519FD6034009CB08D /* icon */ = {
isa = PBXGroup;
children = (
DAD0C5F619FD6034009CB08D /* icon_128x128.png */,
DAD0C5F719FD6034009CB08D /* icon_128x128@2x.png */,
DAD0C5F819FD6034009CB08D /* icon_16x16.png */,
DAD0C5F919FD6034009CB08D /* icon_16x16@2x.png */,
DAD0C5FA19FD6034009CB08D /* icon_256x256.png */,
DAD0C5FB19FD6034009CB08D /* icon_256x256@2x.png */,
DAD0C5FC19FD6034009CB08D /* icon_32x32.png */,
DAD0C5FD19FD6034009CB08D /* icon_32x32@2x.png */,
DAD0C5FE19FD6034009CB08D /* icon_512x512.png */,
DAD0C5FF19FD6034009CB08D /* icon_512x512@2x.png */,
);
path = icon;
sourceTree = "<group>";
};
DAD9B5E2176299B9001835F9 /* Products */ = {
@@ -1660,6 +1676,9 @@
DAFE45D715039823003ABA7C /* Pearl */ = {
isa = PBXGroup;
children = (
DAADCC3E19FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h */,
DAADCC3F19FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h */,
DAADCC4019FAFFAD00987B1D /* NSPersistentStore+PearlMigration.m */,
DA8ED891192906920099B726 /* PearlTween.m */,
DA8ED892192906920099B726 /* PearlTween.h */,
DA8ED893192906920099B726 /* include */,
@@ -1750,22 +1769,6 @@
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
DA2508F419513C1400AC23F1 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
DA4425C91557BED40052177D /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
DACA22BC1705DE7D002C6C22 /* NSError+UbiquityStoreManager.h in Headers */,
DACA22BE1705DE7D002C6C22 /* UbiquityStoreManager.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DAC6326A148680650075AEA5 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
@@ -1807,12 +1810,14 @@
DAFE4A3A15039824003ABA7C /* PearlSCrypt.h in Headers */,
DA30E9CE15722ECA00A68B4C /* NSBundle+PearlMutableInfo.h in Headers */,
DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */,
DAADCC4719FAFFAD00987B1D /* NSNotificationCenter+PearlEasyCleanup.h in Headers */,
DAFE4A63150399FF003ABA88 /* NSObject+PearlKVO.h in Headers */,
DAFE4A63150399FF003ABA94 /* NSDateFormatter+RFC3339.h in Headers */,
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */,
93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */,
DA3509FE15F101A500C14A8E /* PearlQueue.h in Headers */,
DA2CA4EE18D323D3007798F8 /* NSError+PearlFullDescription.h in Headers */,
DAADCC4819FAFFAD00987B1D /* NSPersistentStore+PearlMigration.h in Headers */,
93D39D304F73B3BBA031522A /* PearlProfiler.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1820,44 +1825,11 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
DA2508F519513C1400AC23F1 /* RMBlurredView */ = {
isa = PBXNativeTarget;
buildConfigurationList = DA25091519513C1500AC23F1 /* Build configuration list for PBXNativeTarget "RMBlurredView" */;
buildPhases = (
DA2508F219513C1400AC23F1 /* Sources */,
DA2508F319513C1400AC23F1 /* Frameworks */,
DA2508F419513C1400AC23F1 /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = RMBlurredView;
productName = RMBlurredView;
productReference = DA2508F619513C1400AC23F1 /* libRMBlurredView.a */;
productType = "com.apple.product-type.library.static";
};
DA4425CA1557BED40052177D /* UbiquityStoreManager */ = {
isa = PBXNativeTarget;
buildConfigurationList = DA4425D31557BED40052177D /* Build configuration list for PBXNativeTarget "UbiquityStoreManager" */;
buildPhases = (
DA4425C71557BED40052177D /* Sources */,
DA4425C81557BED40052177D /* Frameworks */,
DA4425C91557BED40052177D /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = UbiquityStoreManager;
productName = iCloudStoreManager;
productReference = DA4425CB1557BED40052177D /* libUbiquityStoreManager.a */;
productType = "com.apple.product-type.library.static";
};
DA5BFA43147E415C00F98B1E /* MasterPassword */ = {
isa = PBXNativeTarget;
buildConfigurationList = DA5BFA6D147E415C00F98B1E /* Build configuration list for PBXNativeTarget "MasterPassword" */;
buildPhases = (
DA4EF9CB19FD4B600032ECB5 /* Run Script: genassets */,
DA5BFA40147E415C00F98B1E /* Sources */,
DA5BFA41147E415C00F98B1E /* Frameworks */,
DA5BFA42147E415C00F98B1E /* Resources */,
@@ -1875,20 +1847,21 @@
productReference = DA5BFA44147E415C00F98B1E /* Master Password.app */;
productType = "com.apple.product-type.application";
};
DABC6C00175D8C85000C15D4 /* RHStatusItemView */ = {
DAADCC4F19FB006500987B1D /* KCOrderedAccessorFix */ = {
isa = PBXNativeTarget;
buildConfigurationList = DABC6C0A175D8C85000C15D4 /* Build configuration list for PBXNativeTarget "RHStatusItemView" */;
buildConfigurationList = DAADCC5E19FB006500987B1D /* Build configuration list for PBXNativeTarget "KCOrderedAccessorFix" */;
buildPhases = (
DABC6BFD175D8C85000C15D4 /* Sources */,
DABC6BFE175D8C85000C15D4 /* Frameworks */,
DAADCC4C19FB006500987B1D /* Sources */,
DAADCC4D19FB006500987B1D /* Frameworks */,
DAADCC4E19FB006500987B1D /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = RHStatusItemView;
productName = RHStatusItemView;
productReference = DABC6C01175D8C85000C15D4 /* libRHStatusItemView.a */;
name = KCOrderedAccessorFix;
productName = KCOrderedAccessorFix;
productReference = DAADCC5019FB006500987B1D /* libKCOrderedAccessorFix.a */;
productType = "com.apple.product-type.library.static";
};
DAC6326B148680650075AEA5 /* jrswizzle */ = {
@@ -1935,7 +1908,7 @@
attributes = {
CLASSPREFIX = MP;
LastTestingUpgradeCheck = 0510;
LastUpgradeCheck = 0600;
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = Lyndir;
TargetAttributes = {
DA5BFA43147E415C00F98B1E = {
@@ -1946,6 +1919,9 @@
};
};
};
DAADCC4F19FB006500987B1D = {
CreatedOnToolsVersion = 6.0.1;
};
};
};
buildConfigurationList = DA5BFA3E147E415C00F98B1E /* Build configuration list for PBXProject "MasterPassword-Mac" */;
@@ -1954,6 +1930,7 @@
hasScannedForEncodings = 0;
knownRegions = (
en,
nl,
);
mainGroup = DA5BFA39147E415C00F98B1E;
productRefGroup = DA5BFA45147E415C00F98B1E /* Products */;
@@ -1969,9 +1946,7 @@
DA5BFA43147E415C00F98B1E /* MasterPassword */,
DAC77CAC148291A600BCF976 /* Pearl */,
DAC6326B148680650075AEA5 /* jrswizzle */,
DA4425CA1557BED40052177D /* UbiquityStoreManager */,
DABC6C00175D8C85000C15D4 /* RHStatusItemView */,
DA2508F519513C1400AC23F1 /* RMBlurredView */,
DAADCC4F19FB006500987B1D /* KCOrderedAccessorFix */,
);
};
/* End PBXProject section */
@@ -2072,6 +2047,21 @@
shellPath = /bin/sh;
shellScript = "";
};
DA4EF9CB19FD4B600032ECB5 /* Run Script: genassets */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script: genassets";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/bin/sh -e";
shellScript = "exec ../../../Scripts/genassets";
showEnvVarsInLog = 0;
};
DA6556E314D55F3000841C99 /* Run Script: GIT version -> Info.plist */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -2083,8 +2073,8 @@
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/bin/bash -e";
shellScript = "PATH+=:/usr/libexec\n\naddPlistWithKey() {\n local key=$1 type=$2 value=$3 plist=${4:-\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"}\n \n PlistBuddy -c \"Delete :'$key'\" \"$plist\" 2>/dev/null || true\n PlistBuddy -c \"Add :'$key' '$type' '$value'\" \"$plist\"\n}\nsetPlistWithKey() {\n local key=$1 value=$2 plist=${3:-\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"}\n \n PlistBuddy -c \"Set :'$key' '$value'\" \"$plist\"\n}\ngetPlistWithKey() {\n local key=$1 plist=${2:-\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"}\n \n PlistBuddy -c \"Print :'$key'\" \"$plist\"\n}\nsetSettingWithTitle() {\n local i title=$1 value=$2 plist=${3:-\"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Settings.bundle/Root.plist\"}\n \n for (( i=0; 1; ++i )); do\n PlistBuddy -c \"Print :PreferenceSpecifiers:$i\" \"$plist\" &>/dev/null || break\n echo \"Checking preference specifier $i\"\n \n [[ $(PlistBuddy -c \"Print :PreferenceSpecifiers:$i:Title\" \"$plist\" 2>/dev/null) = $title ]] || continue\n \n echo \"Correct title, setting value.\"\n PlistBuddy -c \"Set :PreferenceSpecifiers:$i:DefaultValue $value\" \"$plist\"\n break\n done\n}\n\ndescription=$(git describe --always --dirty --long)\nversion=${description%-g*}\nIFS=- read major minor <<< \"$version\"\nprintf -v version '%s.%02d' \"$major\" \"$minor\"\nprintf -v commit '%09d' \"$((16#${description##*-g}))\"\n\naddPlistWithKey GITDescription string \"$description\"\nsetPlistWithKey CFBundleVersion \"${version//.}$commit\" # No separator between version and commit because I had already submitted a CFBundleVersion with a really high major. Cry.\nsetPlistWithKey CFBundleShortVersionString \"$version\"\n\nsetSettingWithTitle \"Build\" \"$commit\"\nsetSettingWithTitle \"Version\" \"$version\"\nsetSettingWithTitle \"Copyright\" \"$(getPlistWithKey NSHumanReadableCopyright)\"\n\nif [[ $DEPLOYMENT_LOCATION = YES ]]; then\n # This build is a release. Do some release checks.\n passed=1\n [[ $description != *-dirty ]] || \\\n { passed=0; echo >&2 \"ERROR: Cannot release a dirty version, first commit any changes.\"; }\n [[ $(PlistBuddy -c \"Print :'API Key'\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Crashlytics.plist\") ]] || \\\n { passed=0; echo >&2 \"ERROR: Cannot release: Crashlytics API key is missing.\"; }\n (( passed )) || \\\n { echo >&2 \"Failed to pass release checks. Fix the above errors and re-try. Aborting.\"; exit 1; }\nfi";
shellPath = "/bin/sh -e";
shellScript = "exec ../../../Scripts/updatePlist";
showEnvVarsInLog = 0;
};
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */ = {
@@ -2105,22 +2095,6 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
DA2508F219513C1400AC23F1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
DA4425C71557BED40052177D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DACA22BB1705DE7D002C6C22 /* UbiquityStoreManager.m in Sources */,
DACA22BD1705DE7D002C6C22 /* NSError+UbiquityStoreManager.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DA5BFA40147E415C00F98B1E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -2131,8 +2105,8 @@
DA5E5CF71724A667003798D8 /* MPAlgorithmV0.m in Sources */,
DA5E5CF81724A667003798D8 /* MPAlgorithmV1.m in Sources */,
DA5E5CF91724A667003798D8 /* MPAppDelegate_Key.m in Sources */,
DA5180CE19FF307E00A587E9 /* MPAppDelegate_Store.m in Sources */,
DA5E5CFA1724A667003798D8 /* MPAppDelegate_Shared.m in Sources */,
DA5E5CFB1724A667003798D8 /* MPAppDelegate_Store.m in Sources */,
DA5E5CFC1724A667003798D8 /* MPConfig.m in Sources */,
DA29992C19C6A89900AF7DF1 /* MasterPassword.xcdatamodeld in Sources */,
DA3B8456190FC89700246EEA /* MPFixable.m in Sources */,
@@ -2143,20 +2117,22 @@
DA5E5D041724A667003798D8 /* MPMacConfig.m in Sources */,
DA5E5D0C1724A667003798D8 /* main.m in Sources */,
93D39C5789EFA607CF788082 /* MPSiteModel.m in Sources */,
DA5180CA19FF2F9200A587E9 /* MPAlgorithmV2.m in Sources */,
93D39F833DEC1C89B2F795AC /* MPPasswordWindowController.m in Sources */,
DA32CFD919CF1C70004F3F0E /* MPGeneratedSiteEntity.m in Sources */,
93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */,
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */,
DA32CFDF19CF1C70004F3F0E /* MPSiteEntity.m in Sources */,
93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */,
93D395E4830290EBB6E71F34 /* MPNoStateButton.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DABC6BFD175D8C85000C15D4 /* Sources */ = {
DAADCC4C19FB006500987B1D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DABC6C15175D8CE1000C15D4 /* RHStatusItemView.m in Sources */,
DAADCC6919FB007F00987B1D /* NSManagedObjectModel+KCOrderedAccessorFix.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2173,6 +2149,7 @@
buildActionMask = 2147483647;
files = (
DAFE4A1415039824003ABA7C /* NSObject+PearlExport.m in Sources */,
DAADCC4919FAFFAD00987B1D /* NSPersistentStore+PearlMigration.m in Sources */,
DAFE4A1615039824003ABA7C /* NSString+PearlNSArrayFormat.m in Sources */,
DAFE4A1815039824003ABA7C /* NSString+PearlSEL.m in Sources */,
DA2CA4ED18D323D3007798F8 /* NSError+PearlFullDescription.m in Sources */,
@@ -2250,54 +2227,6 @@
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
DA25091619513C1500AC23F1 /* Debug-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = "Debug-Mac";
};
DA25091719513C1500AC23F1 /* AdHoc-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = "AdHoc-Mac";
};
DA25091819513C1500AC23F1 /* AppStore-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = "AppStore-Mac";
};
DA4425D41557BED40052177D /* Debug-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = "Debug-Mac";
};
DA4425D51557BED40052177D /* AdHoc-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = "AdHoc-Mac";
};
DA4425D61557BED40052177D /* AppStore-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = "AppStore-Mac";
};
DA5BFA6B147E415C00F98B1E /* Debug-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -2630,23 +2559,26 @@
};
name = "AppStore-Mac";
};
DABC6C0B175D8C85000C15D4 /* Debug-Mac */ = {
DAADCC5F19FB006500987B1D /* Debug-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = "Debug-Mac";
};
DABC6C0C175D8C85000C15D4 /* AdHoc-Mac */ = {
DAADCC6019FB006500987B1D /* AdHoc-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = "AdHoc-Mac";
};
DABC6C0D175D8C85000C15D4 /* AppStore-Mac */ = {
DAADCC6119FB006500987B1D /* AppStore-Mac */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
COMBINE_HIDPI_IMAGES = YES;
};
name = "AppStore-Mac";
@@ -2720,26 +2652,6 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
DA25091519513C1500AC23F1 /* Build configuration list for PBXNativeTarget "RMBlurredView" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DA25091619513C1500AC23F1 /* Debug-Mac */,
DA25091719513C1500AC23F1 /* AdHoc-Mac */,
DA25091819513C1500AC23F1 /* AppStore-Mac */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = "AdHoc-Mac";
};
DA4425D31557BED40052177D /* Build configuration list for PBXNativeTarget "UbiquityStoreManager" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DA4425D41557BED40052177D /* Debug-Mac */,
DA4425D51557BED40052177D /* AdHoc-Mac */,
DA4425D61557BED40052177D /* AppStore-Mac */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = "AdHoc-Mac";
};
DA5BFA3E147E415C00F98B1E /* Build configuration list for PBXProject "MasterPassword-Mac" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@@ -2760,12 +2672,12 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = "AdHoc-Mac";
};
DABC6C0A175D8C85000C15D4 /* Build configuration list for PBXNativeTarget "RHStatusItemView" */ = {
DAADCC5E19FB006500987B1D /* Build configuration list for PBXNativeTarget "KCOrderedAccessorFix" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DABC6C0B175D8C85000C15D4 /* Debug-Mac */,
DABC6C0C175D8C85000C15D4 /* AdHoc-Mac */,
DABC6C0D175D8C85000C15D4 /* AppStore-Mac */,
DAADCC5F19FB006500987B1D /* Debug-Mac */,
DAADCC6019FB006500987B1D /* AdHoc-Mac */,
DAADCC6119FB006500987B1D /* AppStore-Mac */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = "AdHoc-Mac";

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0600"
LastUpgradeVersion = "0610"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0600"
LastUpgradeVersion = "0610"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -41,6 +41,6 @@
@property(nonatomic) IBOutlet UITextField *questionField;
@property(nonatomic) IBOutlet UITextField *answerField;
- (void)setQuestion:(MPSiteQuestionEntity *)question forSite:(MPSiteEntity *)site;
- (void)setQuestion:(MPSiteQuestionEntity *)question forSite:(MPSiteEntity *)site inVC:(MPAnswersViewController *)VC;
@end

View File

@@ -92,7 +92,7 @@
if (!_multiple)
return 0;
return MAX( 2, [[self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]].questions count] );
return [[self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]].questions count] + 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
@@ -118,7 +118,7 @@
MPSiteQuestionEntity *question = nil;
if ([site.questions count] > indexPath.item)
question = site.questions[indexPath.item];
[cell setQuestion:question forSite:site];
[cell setQuestion:question forSite:site inVC:self];
return cell;
}
@@ -217,6 +217,17 @@
} );
}
- (void)didAddQuestion:(MPSiteQuestionEntity *)question toSite:(MPSiteEntity *)site {
NSUInteger newQuestionRow = [site.questions count];
PearlMainQueue( ^{
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:newQuestionRow inSection:1] ]
withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
} );
}
@end
@implementation MPGlobalAnswersCell
@@ -247,14 +258,16 @@
@implementation MPAnswersQuestionCell {
NSManagedObjectID *_siteOID;
NSManagedObjectID *_questionOID;
__weak MPAnswersViewController *_answersVC;
}
#pragma mark - State
- (void)setQuestion:(MPSiteQuestionEntity *)question forSite:(MPSiteEntity *)site {
- (void)setQuestion:(MPSiteQuestionEntity *)question forSite:(MPSiteEntity *)site inVC:(MPAnswersViewController *)answersVC {
_siteOID = site.objectID;
_questionOID = question.objectID;
_answersVC = answersVC;
[self updateAnswerForQuestion:question ofSite:site];
}
@@ -272,9 +285,11 @@
NSString *keyword = textField.text;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
BOOL didAddQuestionObject = NO;
MPSiteEntity *site = [MPSiteEntity existingObjectWithID:_siteOID inContext:context];
MPSiteQuestionEntity *question = [MPSiteQuestionEntity existingObjectWithID:_questionOID inContext:context];
if (!question) {
didAddQuestionObject = YES;
[site addQuestionsObject:question = [MPSiteQuestionEntity insertNewObjectInContext:context]];
question.site = site;
}
@@ -291,6 +306,9 @@
_questionOID = question.objectID;
[self updateAnswerForQuestion:question ofSite:site];
if (didAddQuestionObject)
[_answersVC didAddQuestion:question toSite:site];
}
}];
}

View File

@@ -30,6 +30,7 @@ const long MPAvatarAdd = 10000;
@property(strong, nonatomic) IBOutlet NSLayoutConstraint *avatarSizeConstraint;
@property(strong, nonatomic) IBOutlet NSLayoutConstraint *avatarToTopConstraint;
@property(strong, nonatomic) IBOutlet NSLayoutConstraint *avatarRaisedConstraint;
@property(strong, nonatomic) IBOutlet NSLayoutConstraint *keyboardHeightConstraint;
@end
@@ -66,6 +67,12 @@ const long MPAvatarAdd = 10000;
[self observeKeyPath:@"highlighted" withBlock:^(id from, id to, NSKeyValueChange cause, MPAvatarCell *_self) {
[_self updateAnimated:_self.superview != nil];
}];
PearlAddNotificationObserver( UIKeyboardWillShowNotification, nil, [NSOperationQueue mainQueue],
^(MPAvatarCell *self, NSNotification *note) {
CGRect keyboardRect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboardHeight = CGRectGetHeight( self.window.screen.bounds ) - CGRectGetMinY( keyboardRect );
[self.keyboardHeightConstraint updateConstant:keyboardHeight];
} );
CABasicAnimation *toShadowOpacityAnimation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
toShadowOpacityAnimation.toValue = @0.2f;
@@ -99,6 +106,7 @@ const long MPAvatarAdd = 10000;
- (void)dealloc {
[self removeKeyPathObservers];
PearlRemoveNotificationObservers();
}
#pragma mark - Properties
@@ -264,7 +272,7 @@ const long MPAvatarAdd = 10000;
case MPAvatarModeRaisedAndMinimized: {
[self.avatarSizeConstraint updateConstant:36];
[self.avatarRaisedConstraint updatePriority:UILayoutPriorityDefaultLow];
[self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultHigh];
[self.avatarToTopConstraint updatePriority:UILayoutPriorityDefaultHigh + 2];
[self.nameToCenterConstraint updatePriority:UILayoutPriorityDefaultHigh];
self.nameContainer.alpha = 0;
self.nameContainer.backgroundColor = [UIColor blackColor];

View File

@@ -99,6 +99,8 @@
- (void)setCoached:(BOOL)coached {
[[NSUserDefaults standardUserDefaults] setBool:coached forKey:strf( @"%@.%ld.coached", self.coachedClass, (long)self.coachedVersion )];
if (![[NSUserDefaults standardUserDefaults] synchronize])
wrn( @"Couldn't synchronize after coachmark updates." );
}
@end

View File

@@ -257,8 +257,11 @@
return;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[context deleteObject:[self siteInContext:context]];
MPSiteEntity *site_ = [self siteInContext:context];
if (site_) {
[context deleteObject:site_];
[context saveToStore];
}
}];
} cancelTitle:@"Cancel" destructiveTitle:@"Delete Site" otherTitles:nil];
}
@@ -516,7 +519,7 @@
TimeToCrack timeToCrack;
NSString *timeToCrackString = nil;
id<MPAlgorithm> algorithm = site.algorithm?: MPAlgorithmDefault;
MPAttacker attackHardware = [[MPConfig get].siteAttacker unsignedIntegerValue];
MPAttacker attackHardware = [[MPConfig get].siteAttacker integerValue];
if ([algorithm timeToCrack:&timeToCrack passwordOfType:site.type byAttacker:attackHardware] ||
[algorithm timeToCrack:&timeToCrack passwordString:password byAttacker:attackHardware])
timeToCrackString = NSStringFromTimeToCrack( timeToCrack );

View File

@@ -170,6 +170,7 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
if (controller == _fetchedResultsController) {
@try {
[self.passwordCollectionView performBatchUpdates:^{
[self fetchedItemsDidUpdate];
switch (type) {
@@ -188,6 +189,11 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
}
} completion:nil];
}
@catch (NSException *exception) {
wrn( @"While updating password cells: %@", [exception fullDescription] );
[self.passwordCollectionView reloadData];
}
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo
@@ -310,26 +316,34 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
self.passwordSelectionContainer.alpha = 1;
}];
} );
PearlAddNotificationObserver( MPSignedOutNotification, nil, [NSOperationQueue mainQueue],
PearlAddNotificationObserver( MPSignedOutNotification, nil, nil,
^(MPPasswordsViewController *self, NSNotification *note) {
PearlMainQueue( ^{
_fetchedResultsController = nil;
self.passwordsSearchBar.text = nil;
[self.passwordCollectionView reloadData];
} );
PearlAddNotificationObserver( MPCheckConfigNotification, nil, [NSOperationQueue mainQueue],
} );
PearlAddNotificationObserver( MPCheckConfigNotification, nil, nil,
^(MPPasswordsViewController *self, NSNotification *note) {
PearlMainQueue( ^{
[self updateConfigKey:note.object];
} );
} );
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, nil, nil,
^(MPPasswordsViewController *self, NSNotification *note) {
self->_fetchedResultsController = nil;
PearlMainQueue( ^{
[self.passwordCollectionView reloadData];
} );
} );
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, nil, nil,
^(MPPasswordsViewController *self, NSNotification *note) {
PearlMainQueue( ^{
[self updatePasswords];
[self registerObservers];
} );
} );
NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady];
if (mainContext)
@@ -375,6 +389,7 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
if (![self.fetchedResultsController performFetch:&error])
err( @"Couldn't fetch sites: %@", [error fullDescription] );
@try {
[self.passwordCollectionView performBatchUpdates:^{
[self fetchedItemsDidUpdate];
@@ -397,6 +412,11 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
[self.passwordCollectionView setContentOffset:CGPointMake( 0, -self.passwordCollectionView.contentInset.top )
animated:YES];
}];
}
@catch (NSException *exception) {
wrn( @"While updating password cells: %@", [exception fullDescription] );
[self.passwordCollectionView reloadData];
}
}];
}

View File

@@ -32,6 +32,8 @@
inf( @"Preferences will appear" );
[super viewWillAppear:animated];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"tipped.passwordsPreferences"];
if (![[NSUserDefaults standardUserDefaults] synchronize])
wrn( @"Couldn't synchronize after preferences appearance." );
MPUserEntity *activeUser = [[MPiOSAppDelegate get] activeUserForMainThread];
self.generatedTypeControl.selectedSegmentIndex = [self generatedSegmentIndexForType:activeUser.defaultType];

View File

@@ -37,6 +37,8 @@ PearlEnum( MPDevelopmentFuelConsumption,
return nil;
[[NSUserDefaults standardUserDefaults] setInteger:storeVersion forKey:@"storeVersion"];
if (![[NSUserDefaults standardUserDefaults] synchronize])
wrn( @"Couldn't synchronize store version update." );
return features;
}
@@ -89,9 +91,14 @@ PearlEnum( MPDevelopmentFuelConsumption,
MPStoreProductCell *cell = (MPStoreProductCell *)[super tableView:tableView cellForRowAtIndexPath:indexPath];
if (cell.contentView.translatesAutoresizingMaskIntoConstraints) {
cell.contentView.translatesAutoresizingMaskIntoConstraints = NO;
[cell addConstraint:
[NSLayoutConstraint constraintWithItem:cell attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual
toItem:cell.contentView attribute:NSLayoutAttributeWidth multiplier:1 constant:0]];
[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)
@@ -119,7 +126,7 @@ PearlEnum( MPDevelopmentFuelConsumption,
[cell layoutIfNeeded];
[cell layoutIfNeeded];
dbg_return_tr( cell.contentView.bounds.size.height, @ );
dbg_return_tr( cell.contentView.bounds.size.height, @, indexPath );
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

View File

@@ -34,6 +34,7 @@
@property(weak, nonatomic) IBOutlet UIView *thanksTipContainer;
@property(weak, nonatomic) IBOutlet UIButton *nextAvatarButton;
@property(weak, nonatomic) IBOutlet UIButton *previousAvatarButton;
@property(weak, nonatomic) IBOutlet NSLayoutConstraint *keyboardHeightConstraint;
@property(assign, nonatomic, readonly) BOOL active;

View File

@@ -649,6 +649,12 @@ referenceSizeForFooterInSection:(NSInteger)section {
self.userSelectionContainer.alpha = 1;
}];
} );
PearlAddNotificationObserver( UIKeyboardWillShowNotification, nil, [NSOperationQueue mainQueue],
^(MPUsersViewController *self, NSNotification *note) {
CGRect keyboardRect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboardHeight = CGRectGetHeight( self.view.window.screen.bounds ) - CGRectGetMinY( keyboardRect );
[self.keyboardHeightConstraint updateConstant:keyboardHeight];
} );
NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady];
[UIView animateWithDuration:0.3f animations:^{
@@ -660,7 +666,7 @@ referenceSizeForFooterInSection:(NSInteger)section {
[self.storeLoadingActivity startAnimating];
if (mainContext)
PearlAddNotificationObserver( NSManagedObjectContextObjectsDidChangeNotification, mainContext, [NSOperationQueue mainQueue],
PearlAddNotificationObserver( NSManagedObjectContextObjectsDidChangeNotification, mainContext, nil,
^(MPUsersViewController *self, NSNotification *note) {
NSSet *insertedObjects = note.userInfo[NSInsertedObjectsKey];
NSSet *deletedObjects = note.userInfo[NSDeletedObjectsKey];
@@ -670,11 +676,11 @@ referenceSizeForFooterInSection:(NSInteger)section {
}]] count])
[self reloadUsers];
} );
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, nil, [NSOperationQueue mainQueue],
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresWillChangeNotification, [MPiOSAppDelegate get].storeCoordinator, nil,
^(MPUsersViewController *self, NSNotification *note) {
self.userIDs = nil;
} );
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, nil, [NSOperationQueue mainQueue],
PearlAddNotificationObserver( NSPersistentStoreCoordinatorStoresDidChangeNotification, [MPiOSAppDelegate get].storeCoordinator, nil,
^(MPUsersViewController *self, NSNotification *note) {
[self registerObservers];
[self reloadUsers];

View File

@@ -50,8 +50,11 @@
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
if ([[request.URL absoluteString] rangeOfString:@"thanks.lhunath.com"].location != NSNotFound)
if ([[request.URL absoluteString] rangeOfString:@"thanks.lhunath.com"].location != NSNotFound) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"tipped.thanks"];
if (![[NSUserDefaults standardUserDefaults] synchronize])
wrn( @"Couldn't synchronize thanks tip." );
}
if ([request.URL isEqual:request.mainDocumentURL]) {
self.webNavigationItem.title = request.URL.host;

View File

@@ -138,18 +138,6 @@
@"Find the store from the user pulldown after logging in.", latestFeatures )
viewStyle:UIAlertViewStyleDefault initAlert:nil tappedButtonBlock:nil
cancelTitle:@"Thanks" otherTitles:nil];
MPCheckpoint( MPCheckpointStarted, @{
@"simulator" : PearlStringB( [PearlDeviceUtils isSimulator] ),
@"encrypted" : PearlStringB( [PearlDeviceUtils isAppEncrypted] ),
@"jailbroken" : PearlStringB( [PearlDeviceUtils isJailbroken] ),
@"platform" : [PearlDeviceUtils platform],
#ifdef APPSTORE
@"legal" : PearlStringB([PearlDeviceUtils isAppEncrypted]),
#else
@"legal" : @"YES",
#endif
} );
}
@catch (id exception) {
err( @"During Post-Startup: %@", exception );
@@ -293,6 +281,7 @@
inf( @"Re-activated" );
[[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:nil];
PearlNotMainQueue( ^{
NSString *importHeader = @"# Master Password site export";
NSString *importedSitesString = [UIPasteboard generalPasteboard].string;
if ([importedSitesString length] > [importHeader length] &&
@@ -305,21 +294,15 @@
return;
[self importSites:importedSitesString];
[UIPasteboard generalPasteboard].string = nil;
[UIPasteboard generalPasteboard].string = @"";
} cancelTitle:@"No" otherTitles:@"Import Sites", nil];
} );
[super applicationDidBecomeActive:application];
}
#pragma mark - Behavior
- (void)showReview {
[super showReview];
MPCheckpoint( MPCheckpointReview, nil );
}
- (void)showFeedbackWithLogs:(BOOL)logs forVC:(UIViewController *)viewController {
if (![PearlEMail canSendMail])
@@ -522,8 +505,6 @@
[self signOutAnimated:YES];
if (didReset)
didReset();
MPCheckpoint( MPCheckpointChangeMP, nil );
}
cancelTitle:[PearlStrings get].commonButtonAbort
otherTitles:[PearlStrings get].commonButtonContinue, nil];
@@ -563,19 +544,16 @@
[[Crashlytics sharedInstance] setBoolValue:[[PearlConfig get].askForReviews boolValue] forKey:@"askForReviews"];
[[Crashlytics sharedInstance] setIntValue:[[PearlConfig get].reviewAfterLaunches intValue] forKey:@"reviewAfterLaunches"];
[[Crashlytics sharedInstance] setObjectValue:[PearlConfig get].reviewedVersion forKey:@"reviewedVersion"];
[[Crashlytics sharedInstance] setBoolValue:[PearlDeviceUtils isSimulator] forKey:@"simulator"];
[[Crashlytics sharedInstance] setBoolValue:[PearlDeviceUtils isAppEncrypted] forKey:@"encrypted"];
[[Crashlytics sharedInstance] setBoolValue:[PearlDeviceUtils isJailbroken] forKey:@"jailbroken"];
[[Crashlytics sharedInstance] setObjectValue:[PearlDeviceUtils platform] forKey:@"platform"];
#ifdef APPSTORE
[[Crashlytics sharedInstance] setBoolValue:[PearlDeviceUtils isAppEncrypted] forKey:@"reviewedVersion"];
#else
[[Crashlytics sharedInstance] setBoolValue:YES forKey:@"reviewedVersion"];
#endif
#endif
MPCheckpoint( MPCheckpointConfig, @{
@"rememberLogin" : @([[MPConfig get].rememberLogin boolValue]),
@"sendInfo" : @([[MPiOSConfig get].sendInfo boolValue]),
@"helpHidden" : @([[MPiOSConfig get].helpHidden boolValue]),
@"showQuickStart" : @([[MPiOSConfig get].showSetup boolValue]),
@"firstRun" : @([[PearlConfig get].firstRun boolValue]),
@"launchCount" : NilToNSNull( [PearlConfig get].launchCount ),
@"askForReviews" : @([[PearlConfig get].askForReviews boolValue]),
@"reviewAfterLaunches" : NilToNSNull( [PearlConfig get].reviewAfterLaunches ),
@"reviewedVersion" : NilToNSNull( [PearlConfig get].reviewedVersion )
} );
}
}

View File

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

View File

@@ -11,6 +11,7 @@
93D391ECBD9BD2C64115B5DD /* PearlSizedTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39156E806BB78E04F78B9 /* PearlSizedTextView.m */; };
93D3922A53E41A54832E90D9 /* PearlOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D390FADEB325D8D54A957D /* PearlOverlay.m */; };
93D39262A8A97DB748213309 /* PearlEMail.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D393BB973253D4BAAC84AA /* PearlEMail.m */; };
93D3928D629EA563F9EC4909 /* NSPersistentStore+PearlMigration.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D399C2F3D48E57C4803BDC /* NSPersistentStore+PearlMigration.m */; };
93D392A8777DC30C11361647 /* UITextView+PearlAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39AA10CD00D05937671B1 /* UITextView+PearlAttributes.h */; };
93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; };
93D392FD5E2052F7D7DB3774 /* NSString+MPMarkDown.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39C41A27AA42D044D68AE /* NSString+MPMarkDown.m */; };
@@ -40,6 +41,7 @@
93D39A53D76CA70786423458 /* UICollectionView+PearlReloadFromArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadFromArray.h */; };
93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DEA995041A13DC9CAF7 /* MPPasswordCell.m */; };
93D39A8EA1C49CE43B63F47B /* PearlUICollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D8A953779B35403AF6E /* PearlUICollectionView.m */; };
93D39AA4A0BE66A872CCC02E /* NSPersistentStore+PearlMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D397F4BAFFF7CF3F1B21A4 /* NSPersistentStore+PearlMigration.h */; };
93D39B429C67A62E29DC02DA /* MPRootSegue.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D399493FEDDE74DD1A0C15 /* MPRootSegue.m */; };
93D39B76DD5AB108BA8928E8 /* UIScrollView+PearlAdjustInsets.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39DE2CB351D4E3789462B /* UIScrollView+PearlAdjustInsets.h */; };
93D39B842AB9A5D072810D76 /* NSError+PearlFullDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D398C95847261903D781D3 /* NSError+PearlFullDescription.h */; };
@@ -483,6 +485,7 @@
93D39730673227EFF6DEFF19 /* MPSetupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSetupViewController.h; sourceTree = "<group>"; };
93D3977321EB249981821AB0 /* UITextView+PearlAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextView+PearlAttributes.m"; sourceTree = "<group>"; };
93D3979190DACEBD1F6AE9F4 /* MPLogsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPLogsViewController.m; sourceTree = "<group>"; };
93D397F4BAFFF7CF3F1B21A4 /* NSPersistentStore+PearlMigration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPersistentStore+PearlMigration.h"; sourceTree = "<group>"; };
93D398567FD02DB2647B8CF3 /* PearlNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlNavigationController.h; sourceTree = "<group>"; };
93D398C95847261903D781D3 /* NSError+PearlFullDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+PearlFullDescription.h"; sourceTree = "<group>"; };
93D3990E0CD1B5CF9FBB2C07 /* MPWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPWebViewController.m; sourceTree = "<group>"; };
@@ -491,6 +494,7 @@
93D39975CE5AEC99E3F086C7 /* MPPasswordCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordCell.h; sourceTree = "<group>"; };
93D3999693660C89A7465F4E /* MPCoachmarkViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCoachmarkViewController.h; sourceTree = "<group>"; };
93D399A8E3181B442D347CD7 /* MPAlgorithmV2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAlgorithmV2.m; sourceTree = "<group>"; };
93D399C2F3D48E57C4803BDC /* NSPersistentStore+PearlMigration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSPersistentStore+PearlMigration.m"; sourceTree = "<group>"; };
93D399E571F61E50A9BF8FAF /* MPUsersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUsersViewController.m; sourceTree = "<group>"; };
93D399F244BB522A317811BB /* MPFixable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPFixable.h; sourceTree = "<group>"; };
93D39A1DDFA09AE2E14D26DC /* UIResponder+PearlFirstResponder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIResponder+PearlFirstResponder.m"; sourceTree = "<group>"; };
@@ -2599,8 +2603,6 @@
DAFE45FC15039823003ABA7C /* Pearl-Crypto */,
DAFE460715039823003ABA7C /* Pearl-UIKit */,
DAC77CB1148291A600BCF976 /* Pearl-Prefix.pch */,
DACA29751705E2BD002C6C22 /* jrswizzle */,
DACA29B41705E2DE002C6C22 /* uicolor-utilities */,
);
path = Pearl;
sourceTree = "<group>";
@@ -2612,6 +2614,8 @@
DA32D03719D111EB004F3F0E /* KCOrderedAccessorFix */,
DAA141181922FED80032B392 /* iOS */,
DAFC5662172C57EC00CB5CC5 /* InAppSettingsKit */,
DACA29751705E2BD002C6C22 /* jrswizzle */,
DACA29B41705E2DE002C6C22 /* uicolor-utilities */,
DAC77CAF148291A600BCF976 /* Pearl */,
);
name = External;
@@ -2653,8 +2657,7 @@
DACA29771705E2BD002C6C22 /* JRSwizzle.h */,
DACA298C1705E2BD002C6C22 /* JRSwizzle.m */,
);
name = jrswizzle;
path = External/jrswizzle;
path = jrswizzle;
sourceTree = "<group>";
};
DACA29B41705E2DE002C6C22 /* uicolor-utilities */ = {
@@ -2665,8 +2668,7 @@
DACA29BA1705E2DE002C6C22 /* UIColor+Expanded.m */,
DACA29BB1705E2DE002C6C22 /* UIColor+HSV.m */,
);
name = "uicolor-utilities";
path = "External/uicolor-utilities";
path = "uicolor-utilities";
sourceTree = "<group>";
};
DAFC5662172C57EC00CB5CC5 /* InAppSettingsKit */ = {
@@ -2792,6 +2794,8 @@
93D39F9106F2CCFB94283188 /* NSError+PearlFullDescription.m */,
93D398C95847261903D781D3 /* NSError+PearlFullDescription.h */,
93D391AA32F24290C424438E /* NSNotificationCenter+PearlEasyCleanup.h */,
93D399C2F3D48E57C4803BDC /* NSPersistentStore+PearlMigration.m */,
93D397F4BAFFF7CF3F1B21A4 /* NSPersistentStore+PearlMigration.h */,
);
path = Pearl;
sourceTree = "<group>";
@@ -3015,6 +3019,7 @@
93D393DB5325820241BA90A7 /* PearlSizedTextView.h in Headers */,
93D392A8777DC30C11361647 /* UITextView+PearlAttributes.h in Headers */,
93D39A53D76CA70786423458 /* UICollectionView+PearlReloadFromArray.h in Headers */,
93D39AA4A0BE66A872CCC02E /* NSPersistentStore+PearlMigration.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3149,7 +3154,7 @@
isa = PBXProject;
attributes = {
CLASSPREFIX = MP;
LastUpgradeCheck = 0600;
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = Lyndir;
TargetAttributes = {
DA32D01F19D111C6004F3F0E = {
@@ -3485,8 +3490,8 @@
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/bin/bash -e";
shellScript = "PATH+=:/usr/libexec\n\naddPlistWithKey() {\n local key=$1 type=$2 value=$3 plist=${4:-\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"}\n \n PlistBuddy -c \"Delete :'$key'\" \"$plist\" 2>/dev/null || true\n PlistBuddy -c \"Add :'$key' '$type' '$value'\" \"$plist\"\n}\nsetPlistWithKey() {\n local key=$1 value=$2 plist=${3:-\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"}\n \n PlistBuddy -c \"Set :'$key' '$value'\" \"$plist\"\n}\ngetPlistWithKey() {\n local key=$1 plist=${2:-\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"}\n \n PlistBuddy -c \"Print :'$key'\" \"$plist\"\n}\nsetSettingWithTitle() {\n local i title=$1 value=$2 plist=${3:-\"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Settings.bundle/Root.plist\"}\n \n for (( i=0; 1; ++i )); do\n PlistBuddy -c \"Print :PreferenceSpecifiers:$i\" \"$plist\" &>/dev/null || break\n echo \"Checking preference specifier $i\"\n \n [[ $(PlistBuddy -c \"Print :PreferenceSpecifiers:$i:Title\" \"$plist\" 2>/dev/null) = $title ]] || continue\n \n echo \"Correct title, setting value.\"\n PlistBuddy -c \"Set :PreferenceSpecifiers:$i:DefaultValue $value\" \"$plist\"\n break\n done\n}\n\ndescription=$(git describe --always --dirty --long)\nversion=${description%-g*}\nIFS=- read major minor <<< \"$version\"\nprintf -v version '%s.%02d' \"$major\" \"$minor\"\nprintf -v commit '%09d' \"$((16#${description##*-g}))\"\n\naddPlistWithKey GITDescription string \"$description\"\nsetPlistWithKey CFBundleVersion \"${version//.}$commit\" # No separator between version and commit because I had already submitted a CFBundleVersion with a really high major. Cry.\nsetPlistWithKey CFBundleShortVersionString \"$version\"\n\nsetSettingWithTitle \"Build\" \"$commit\"\nsetSettingWithTitle \"Version\" \"$version\"\nsetSettingWithTitle \"Copyright\" \"$(getPlistWithKey NSHumanReadableCopyright)\"\n\nif [[ $DEPLOYMENT_LOCATION = YES ]]; then\n # This build is a release. Do some release checks.\n passed=1\n [[ $description != *-dirty ]] || \\\n { passed=0; echo >&2 \"ERROR: Cannot release a dirty version, first commit any changes.\"; }\n [[ $(PlistBuddy -c \"Print :'API Key'\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Crashlytics.plist\") ]] || \\\n { passed=0; echo >&2 \"ERROR: Cannot release: Crashlytics API key is missing.\"; }\n (( passed )) || \\\n { echo >&2 \"Failed to pass release checks. Fix the above errors and re-try. Aborting.\"; exit 1; }\nfi";
shellPath = "/bin/sh -e";
shellScript = "exec ../../../Scripts/updatePlist";
};
DA8D88E019DA412A00B189D0 /* Run Script: genassets */ = {
isa = PBXShellScriptBuildPhase;
@@ -3500,7 +3505,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/bin/sh -e";
shellScript = "exec env PATH=\"/usr/local/bin:$PATH\" ../../../Scripts/genassets";
shellScript = "exec ../../../Scripts/genassets";
showEnvVarsInLog = 0;
};
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */ = {
@@ -3681,6 +3686,7 @@
93D391ECBD9BD2C64115B5DD /* PearlSizedTextView.m in Sources */,
93D39E34FD28D24FE3442C48 /* UITextView+PearlAttributes.m in Sources */,
93D39D47FC623E91FC39D20C /* UICollectionView+PearlReloadFromArray.m in Sources */,
93D3928D629EA563F9EC4909 /* NSPersistentStore+PearlMigration.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3932,7 +3938,7 @@
Reveal,
);
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "78fbee53-abe7-4a47-b917-c223df3a6952";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "3251b7d3-04df-4c8e-a410-d020ffc92d10";
SKIP_INSTALL = NO;
TARGETED_DEVICE_FAMILY = 1;
};
@@ -3958,7 +3964,7 @@
"$(inherited)",
);
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "d02e889e-2701-47eb-b843-4f16c431b284";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "59b587d0-3ef3-4691-9f12-c48f7f283002";
SKIP_INSTALL = NO;
STRIP_INSTALLED_PRODUCT = YES;
TARGETED_DEVICE_FAMILY = 1;
@@ -4065,7 +4071,7 @@
"$(inherited)",
);
PROVISIONING_PROFILE = "";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "48f9bae8-b80e-41c7-8792-663102bed54f";
"PROVISIONING_PROFILE[sdk=iphoneos*]" = "a1d8cfc8-b8db-4544-af34-28cc75e46c40";
SKIP_INSTALL = NO;
STRIP_INSTALLED_PRODUCT = YES;
TARGETED_DEVICE_FAMILY = 1;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0600"
LastUpgradeVersion = "0610"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0600"
LastUpgradeVersion = "0610"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -126,7 +126,7 @@ To see a site&apos;s password anyway, tap and hold your finger down for a while
<integer>0</integer>
<integer>1</integer>
<integer>2</integer>
<string>3</string>
<integer>3</integer>
</array>
</dict>
<dict>

View File

@@ -133,7 +133,6 @@
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" constant="216" id="GcG-kq-fq2"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="216" id="yUb-JQ-gv0"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rWM-08-aab" userLabel="Users Root">
@@ -173,10 +172,10 @@
</constraints>
</view>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="ui_spinner.png" translatesAutoresizingMaskIntoConstraints="NO" id="y4j-ds-HM7" userLabel="Spinner">
<rect key="frame" x="52" y="-13" width="110" height="110"/>
<rect key="frame" x="52" y="216" width="110" height="110"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar-0.png" translatesAutoresizingMaskIntoConstraints="NO" id="Aca-he-7Qi" userLabel="Avatar">
<rect key="frame" x="52" y="-13" width="110" height="110"/>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="755" verticalCompressionResistancePriority="755" image="avatar-0.png" translatesAutoresizingMaskIntoConstraints="NO" id="Aca-he-7Qi" userLabel="Avatar">
<rect key="frame" x="52" y="216" width="110" height="110"/>
<color key="tintColor" red="0.47450980390000003" green="0.86666666670000003" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="110" id="Ezz-dq-dfq"/>
@@ -184,7 +183,7 @@
</constraints>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0Sa-Vg-EEI" userLabel="Name Backdrop">
<rect key="frame" x="43" y="34" width="128.5" height="16"/>
<rect key="frame" x="43" y="263" width="128.5" height="16"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalCompressionResistancePriority="1000" text="Maarten Billemont" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cLT-s0-4SQ" userLabel="Name Field">
<rect key="frame" x="5" y="0.0" width="118.5" height="16"/>
@@ -206,7 +205,7 @@
</view>
<constraints>
<constraint firstItem="J7b-uT-zY2" firstAttribute="leading" secondItem="Zab-uQ-uk9" secondAttribute="leading" id="1Sw-vq-MuH"/>
<constraint firstItem="CQo-kd-XAU" firstAttribute="centerY" secondItem="Aca-he-7Qi" secondAttribute="centerY" priority="750" id="1zu-ay-NUc"/>
<constraint firstItem="CQo-kd-XAU" firstAttribute="centerY" secondItem="Aca-he-7Qi" secondAttribute="centerY" priority="250" id="1zu-ay-NUc"/>
<constraint firstItem="y4j-ds-HM7" firstAttribute="centerX" secondItem="Aca-he-7Qi" secondAttribute="centerX" id="D6m-xp-Ja0"/>
<constraint firstAttribute="centerX" secondItem="0Sa-Vg-EEI" secondAttribute="centerX" id="EYH-CQ-6TX"/>
<constraint firstItem="0Sa-Vg-EEI" firstAttribute="top" secondItem="Aca-he-7Qi" secondAttribute="bottom" priority="500" constant="8" symbolic="YES" id="F67-h9-FDi"/>
@@ -218,16 +217,18 @@
<constraint firstItem="y4j-ds-HM7" firstAttribute="centerY" secondItem="Aca-he-7Qi" secondAttribute="centerY" id="b7q-13-zb4"/>
<constraint firstAttribute="centerY" secondItem="Aca-he-7Qi" secondAttribute="centerY" priority="500" id="fKx-ZZ-sJa"/>
<constraint firstItem="CQo-kd-XAU" firstAttribute="top" secondItem="Zab-uQ-uk9" secondAttribute="top" constant="20" id="kO6-Hn-9ab"/>
<constraint firstItem="Aca-he-7Qi" firstAttribute="centerY" relation="greaterThanOrEqual" secondItem="Zab-uQ-uk9" secondAttribute="top" priority="751" constant="60" id="qu4-jD-JoX"/>
<constraint firstAttribute="bottom" secondItem="J7b-uT-zY2" secondAttribute="bottom" id="sKD-RY-oA8"/>
<constraint firstItem="CQo-kd-XAU" firstAttribute="leading" secondItem="Zab-uQ-uk9" secondAttribute="leading" id="trm-Bp-zf3"/>
<constraint firstItem="y4j-ds-HM7" firstAttribute="height" secondItem="Aca-he-7Qi" secondAttribute="height" id="wyT-4c-SaV"/>
<constraint firstItem="J7b-uT-zY2" firstAttribute="top" secondItem="Aca-he-7Qi" secondAttribute="centerY" priority="250" constant="180" id="xgw-C1-V3h"/>
<constraint firstItem="J7b-uT-zY2" firstAttribute="top" secondItem="Aca-he-7Qi" secondAttribute="centerY" priority="750" constant="180" id="xgw-C1-V3h"/>
</constraints>
<connections>
<outlet property="avatarImageView" destination="Aca-he-7Qi" id="Me2-jn-hSX"/>
<outlet property="avatarRaisedConstraint" destination="xgw-C1-V3h" id="cHf-dg-hD9"/>
<outlet property="avatarSizeConstraint" destination="Ezz-dq-dfq" id="FLf-Gq-Pdw"/>
<outlet property="avatarToTopConstraint" destination="1zu-ay-NUc" id="i4J-5Z-Ky7"/>
<outlet property="keyboardHeightConstraint" destination="KPB-We-gf0" id="gG1-Fl-VqV"/>
<outlet property="nameContainer" destination="0Sa-Vg-EEI" id="VLy-AI-Yh8"/>
<outlet property="nameLabel" destination="cLT-s0-4SQ" id="85r-AJ-Zkb"/>
<outlet property="nameToCenterConstraint" destination="Ht7-Iz-cAW" id="zeF-2U-6GW"/>
@@ -460,9 +461,11 @@
<constraints>
<constraint firstAttribute="centerX" secondItem="VDd-oM-ZOO" secondAttribute="centerX" id="0j9-vM-WFA"/>
<constraint firstItem="zCP-wo-gTl" firstAttribute="top" secondItem="rWM-08-aab" secondAttribute="top" constant="20" id="1ly-9W-ybj"/>
<constraint firstItem="cF4-TE-GEj" firstAttribute="bottom" secondItem="9u7-pu-Wtv" secondAttribute="top" id="3oq-Zs-Ann"/>
<constraint firstItem="cF4-TE-GEj" firstAttribute="bottom" secondItem="9u7-pu-Wtv" secondAttribute="top" priority="500" id="3oq-Zs-Ann"/>
<constraint firstItem="0Um-Ot-hI6" firstAttribute="top" secondItem="zCP-wo-gTl" secondAttribute="centerY" id="6zz-7f-HLz"/>
<constraint firstAttribute="trailing" secondItem="L6J-pd-gcp" secondAttribute="trailing" id="9fV-8e-y3E"/>
<constraint firstItem="fUK-gJ-NRE" firstAttribute="centerY" relation="greaterThanOrEqual" secondItem="L6J-pd-gcp" secondAttribute="top" constant="60" id="ADW-TA-Iha"/>
<constraint firstItem="9u7-pu-Wtv" firstAttribute="centerY" relation="greaterThanOrEqual" secondItem="L6J-pd-gcp" secondAttribute="top" constant="60" id="AQZ-W6-Xkf"/>
<constraint firstItem="L6J-pd-gcp" firstAttribute="leading" secondItem="rWM-08-aab" secondAttribute="leading" id="BcO-0y-Nih"/>
<constraint firstAttribute="centerX" secondItem="cF4-TE-GEj" secondAttribute="centerX" id="CvC-rv-8KE"/>
<constraint firstItem="qp1-nX-o4i" firstAttribute="leading" secondItem="rWM-08-aab" secondAttribute="leading" id="DY1-Ad-Mbi"/>
@@ -470,6 +473,7 @@
<constraint firstItem="0Um-Ot-hI6" firstAttribute="centerX" secondItem="zCP-wo-gTl" secondAttribute="centerX" id="OJA-7u-h1T"/>
<constraint firstAttribute="bottom" secondItem="XEP-O3-ayG" secondAttribute="bottom" id="PpW-Of-YOc"/>
<constraint firstAttribute="trailing" secondItem="fUK-gJ-NRE" secondAttribute="trailing" id="TBr-pS-kEK"/>
<constraint firstItem="cF4-TE-GEj" firstAttribute="top" relation="greaterThanOrEqual" secondItem="L6J-pd-gcp" secondAttribute="top" constant="4" id="VHh-25-0mJ"/>
<constraint firstAttribute="trailing" secondItem="qp1-nX-o4i" secondAttribute="trailing" id="cOq-BS-Xmo"/>
<constraint firstAttribute="centerY" secondItem="VDd-oM-ZOO" secondAttribute="centerY" id="dxP-im-1dM"/>
<constraint firstItem="zCP-wo-gTl" firstAttribute="leading" secondItem="rWM-08-aab" secondAttribute="leading" id="jBY-Gd-orW"/>
@@ -486,9 +490,9 @@
<constraint firstItem="VGz-R0-vMD" firstAttribute="top" secondItem="X8H-vh-j7B" secondAttribute="bottom" id="8Ed-3Y-ll0"/>
<constraint firstAttribute="trailing" secondItem="X8H-vh-j7B" secondAttribute="trailing" id="8Gr-Dq-UpZ"/>
<constraint firstAttribute="bottom" secondItem="rWM-08-aab" secondAttribute="bottom" id="9Yx-cj-wHh"/>
<constraint firstItem="X8H-vh-j7B" firstAttribute="top" secondItem="9u7-pu-Wtv" secondAttribute="centerY" constant="180" id="Gp5-h6-53S"/>
<constraint firstItem="X8H-vh-j7B" firstAttribute="top" secondItem="9u7-pu-Wtv" secondAttribute="centerY" priority="500" constant="180" id="Gp5-h6-53S"/>
<constraint firstItem="rWM-08-aab" firstAttribute="leading" secondItem="DOr-Xu-P9q" secondAttribute="leading" id="Il8-kg-Dra"/>
<constraint firstItem="X8H-vh-j7B" firstAttribute="top" secondItem="fUK-gJ-NRE" secondAttribute="centerY" constant="180" id="PgC-ZL-cQo"/>
<constraint firstItem="X8H-vh-j7B" firstAttribute="top" secondItem="fUK-gJ-NRE" secondAttribute="centerY" priority="500" constant="180" id="PgC-ZL-cQo"/>
<constraint firstAttribute="trailing" secondItem="rWM-08-aab" secondAttribute="trailing" id="UPP-1n-zIe"/>
<constraint firstItem="X8H-vh-j7B" firstAttribute="top" secondItem="qp1-nX-o4i" secondAttribute="bottom" constant="20" id="WdK-tA-njz"/>
<constraint firstItem="X8H-vh-j7B" firstAttribute="leading" secondItem="DOr-Xu-P9q" secondAttribute="leading" id="jbn-ko-MPq"/>
@@ -506,6 +510,7 @@
<outlet property="entryTipSubtitleLabel" destination="KhE-Yj-Kvm" id="G0X-19-RmH"/>
<outlet property="entryTipTitleLabel" destination="ZI7-qg-7OW" id="dZj-rZ-efd"/>
<outlet property="footerContainer" destination="XEP-O3-ayG" id="9cI-p9-av3"/>
<outlet property="keyboardHeightConstraint" destination="GcG-kq-fq2" id="V1s-Sz-0Zp"/>
<outlet property="marqueeButton" destination="4md-Gp-SLG" id="bUt-IL-8P1"/>
<outlet property="nextAvatarButton" destination="fUK-gJ-NRE" id="5qo-lK-rSa"/>
<outlet property="preferencesTipContainer" destination="0Um-Ot-hI6" id="Cv8-Bp-ZZs"/>
@@ -2809,7 +2814,7 @@ See </string>
<outlet property="purchasedIndicator" destination="yZX-ns-8oV" id="7x0-eq-oSs"/>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreProductCellFuel" rowHeight="394" id="le3-Q5-MSO" userLabel="Fuel" customClass="MPStoreProductCell">
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreProductCellFuel" rowHeight="407" id="le3-Q5-MSO" userLabel="Fuel" customClass="MPStoreProductCell">
<rect key="frame" x="0.0" y="0.0" width="320" height="97"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="le3-Q5-MSO" id="SzQ-Y5-XIF">
@@ -2823,12 +2828,13 @@ See </string>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fz2-AO-aGW">
<rect key="frame" x="20" y="254" width="335" height="119.5"/>
<rect key="frame" x="20" y="254" width="335" height="132"/>
<string key="text">You really love Master Password and how it's solving your password problems. You're eager to encourage the maintenance, technical support and development of new features. I am a one-man shop, fuel enables me to allocate more work hours to Master Password.
UPCOMING:
Safari integration
Touch ID support
Multi-platform support
Your feedback</string>
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="11"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
@@ -2881,7 +2887,6 @@ invested: 3.7 work hours</string>
<constraint firstItem="Jnv-uN-xeg" firstAttribute="bottom" secondItem="EbU-DV-fKF" secondAttribute="bottom" id="KbL-rF-pVN"/>
<constraint firstItem="Jnv-uN-xeg" firstAttribute="top" secondItem="PnG-hP-syh" secondAttribute="bottom" constant="8" symbolic="YES" id="OZV-m1-YZ1"/>
<constraint firstItem="dsR-fr-dY4" firstAttribute="top" secondItem="SzQ-Y5-XIF" secondAttribute="top" constant="20" id="VH2-O8-CGj"/>
<constraint firstAttribute="bottom" secondItem="fz2-AO-aGW" secondAttribute="bottom" constant="20" symbolic="YES" id="Wqo-Le-AcG"/>
<constraint firstItem="eS4-59-Xny" firstAttribute="centerX" secondItem="PnG-hP-syh" secondAttribute="centerX" id="ZbQ-LX-kmS"/>
<constraint firstItem="kYb-j4-32C" firstAttribute="leading" secondItem="dsR-fr-dY4" secondAttribute="leading" id="bih-Ha-Tz7"/>
<constraint firstItem="EbU-DV-fKF" firstAttribute="leading" secondItem="Jnv-uN-xeg" secondAttribute="trailing" constant="8" symbolic="YES" id="cku-JX-4bK"/>
@@ -2891,6 +2896,7 @@ invested: 3.7 work hours</string>
<constraint firstAttribute="centerX" secondItem="PnG-hP-syh" secondAttribute="centerX" id="gO5-ME-YVO"/>
<constraint firstAttribute="trailing" secondItem="EbU-DV-fKF" secondAttribute="trailing" constant="20" id="hae-Jv-wOU"/>
<constraint firstAttribute="trailing" secondItem="fz2-AO-aGW" secondAttribute="trailing" constant="20" id="vlt-qH-1Xx"/>
<constraint firstAttribute="bottom" secondItem="fz2-AO-aGW" secondAttribute="bottom" constant="20" symbolic="YES" id="xkO-cL-7m2"/>
<constraint firstItem="eS4-59-Xny" firstAttribute="centerY" secondItem="PnG-hP-syh" secondAttribute="centerY" id="yUc-2F-y1r"/>
</constraints>
</tableViewCellContentView>

Binary file not shown.

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>app</key>
<string>com.bohemiancoding.sketch3</string>
<key>build</key>
<integer>8053</integer>
<key>commit</key>
<string>104f8b8798002207eebbbee810c02306c5ce85c9</string>
<key>fonts</key>
<array>
<string>SourceCodePro-Light</string>
<string>LucidaGrande</string>
<string>HelveticaNeue-Medium</string>
</array>
<key>length</key>
<integer>918726</integer>
<key>version</key>
<integer>37</integer>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 KiB

View File

@@ -465,44 +465,6 @@ readwhile() {
# ___________________________________________________________________________
# |__ pushqueue ______________________________________________________________|
#
# pushqueue element ...
#
# Pushes the given arguments as elements onto the queue.
#
pushqueue() {
[[ $_queue ]] || {
coproc _queue {
while IFS= read -r -d ''; do
printf '%s\0' "$REPLY"
done
}
}
printf '%s\0' "$@" >&"${_queue[1]}"
} # _____________________________________________________________________
# __________________________________________________________________________
# |__ popqueue ______________________________________________________________|
#
# popqueue
#
# Pops one element off the queue.
# If no elements are available on the queue, this command fails with exit code 1.
#
popqueue() {
local REPLY
[[ $_queue ]] && read -t0 <&"${_queue[0]}" || return
IFS= read -r -d '' <&"${_queue[0]}"
printf %s "$REPLY"
} # _____________________________________________________________________
# ______________________________________________________________________
# |__ Latest ____________________________________________________________|
#

View File

@@ -2,10 +2,24 @@
# See https://developer.apple.com/library/ios/qa/qa1686/_index.html
cd "${BASH_SOURCE%/*}"
source bashlib
set -e
cd ..
export PATH+=/usr/local/bin
# icons format: [pixel size]@[scale]@[idiom]@[os]:[filename] -- if os is "anything lower", omit it
icons=(
# Mac
16@1@mac@:
32@2@mac@:
32@1@mac@:
64@2@mac@:
128@1@mac@:
256@2@mac@:
256@1@mac@:
512@2@mac@:
512@1@mac@:
1024@2@mac@:
# iPhone
180@3@iphone@8.0:Icon-60@3x.png
120@3@iphone@8.0:Icon-Small-40@3x.png
120@2@iphone@7.0:Icon-60@2x.png
@@ -15,7 +29,7 @@ icons=(
58@2@iphone@:Icon-Small@2x.png
# 57@1@iphone@:Icon.png
# 29@1@iphone@:Icon-Small.png
#
# iPad
76@1@ipad@7.0:Icon-76.png
152@2@ipad@7.0:Icon-76@2x.png
40@1@ipad@7.0:Icon-Small-40.png
@@ -64,8 +78,10 @@ appiconset="$xcassets/AppIcon.appiconset"
launchimage="$xcassets/LaunchImage.launchimage"
ios_icon=MasterPassword/Resources/Media/ios/icon
ios_launch=MasterPassword/Resources/Media/ios/launch
mac_icon=MasterPassword/Resources/Media/mac/icon
if [[ "$(latest "$ios_icon"/*)" -nt "$appiconset/Contents.json" ]]; then
if [[ "$(latest "$ios_icon"/*)" -nt "$appiconset/Contents.json" ]] ||
[[ "$(latest "$mac_icon"/*)" -nt "$appiconset/Contents.json" ]]; then
rm -rf "$appiconset"; mkdir -p "$appiconset"
{
comma=
@@ -75,7 +91,19 @@ if [[ "$(latest "$ios_icon"/*)" -nt "$appiconset/Contents.json" ]]; then
IFS=@ read px scale idiom os <<< "$icon"
pt=$(( px / scale ))
if imageProps=$(copyImage "$ios_icon/$filename" "$appiconset/$filename"); then
suffix=
[[ $scale != 1 ]] && suffix=@${scale}x
[[ $filename ]] || filename="icon_${pt}x${pt}${suffix}.png"
source=$ios_icon/$filename
if [[ ! -e $source ]]; then
source=$mac_icon/$filename
if [[ ! -e $source ]]; then
err 'No icon for: %s' "$filename"
exit 1
fi
fi
if imageProps=$(copyImage "$source" "$appiconset/$filename"); then
printf '%s{"size":"%dx%d","filename":"%s","scale":"%sx"' \
"$comma" "$pt" "$pt" "$filename" "$scale"
[[ $idiom ]] && printf ',"idiom":"%s"' "$idiom"

View File

@@ -14,7 +14,7 @@
<link rel="shortcut icon" href="img/favicon.png" type="image/x-png" />
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-responsive.min.css">
<link rel="stylesheet" href="css/main.css?1">
<link rel="stylesheet" href="css/main.css?7">
<script src="js/vendor/modernizr-2.6.2.min.js"></script>
<script src="js/vendor/prefixfree.min.js"></script>
@@ -35,18 +35,16 @@
<a class="brand" href="./">●●●|</a>
<div class="nav-collapse collapse">
<ul class="nav">
<li><a href="./">App</a></li>
<li><a href="security.html">Security</a></li>
<li><a href="faq.html">FAQ</a></li>
<li class="active"><a href="algorithm.html">Algorithm</a></li>
<li><a href="support.html">Support</a></li>
<li><a href="http://github.com/Lyndir/MasterPassword/" onclick="_gaq.push(['_trackPageview', '/outbound/github']);">Source (GPL)</a></li>
<li><a href="what.html">What is it? How do I use it?</a></li>
<li><a href="security.html">Is it safe?</a></li>
<li class="active"><a href="algorithm.html">How does it work?</a></li>
</ul>
<ul class="nav pull-right">
<li><a href="irc://irc.freenode.net/#masterpassword" onclick="_gaq.push(['_trackPageview', '/outbound/irc']);">#masterpassword (freenode)</a></li>
<li><a href="irc://irc.freenode.net/#masterpassword" onclick="_gaq.push(['_trackPageview', '/outbound/irc']);">#masterpassword</a></li>
<li class="divider-vertical"></li>
<li><a href="MasterPassword_PressKit.zip" onclick="_gaq.push(['_trackPageview', '/outbound/presskit']);">⬇ Press Kit</a></li>
<li><a href="http://itunes.apple.com/app/id510296984" onclick="goog_report_conversion('index-fixed-header');_gaq.push(['_trackPageview', '/outbound/itunes']);" class="img"><img src="img/appstore.svg" /></a></li>
<li><a href="faq.html">FAQ</a></li>
<li><a href="support.html">Support</a></li>
<li><a href="http://github.com/Lyndir/MasterPassword/" onclick="_gaq.push(['_trackPageview', '/outbound/github']);">Source</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
@@ -77,42 +75,6 @@
<p><b>Master Password is <em>an algorithm used to generate unique passwords</em></b> for websites, email accounts, or anything else <em>based only on easily reproducible input</em>.<br />
The goal is a process that avoids all the problems involved with other password solutions.</p>
<p>The Master Password algorithm is <i>open</i>: this page describes its inner workings in detail. We believe the following is an important lesson we should all learn: Regardless of how much encryption a solution claims, <a href="http://www.geekzone.co.nz/foobar/5823" onclick="_gaq.push(['_trackPageview', '/outbound/skype']);">if you don't know how it works, you <strong>cannot</strong> assume it is secure</a> (at least, not the kind of secure you care about).</p>
<h1>The Password Problem</h1>
<img class="pull-right" src="img/thumb-authenticate.png" />
<p>Passwords are used to authenticate you to someone else. That means, convince someone that you really are who you say you are. The theory is that when you two are the only ones that know a certain secret word, then the other party can be certain of your identity when you prove to them you know the secret word.</p>
<p>Authentication using passwords is pretty good in theory but <strong>fails when</strong> the password is either:
<ul>
<li>Easily guessed by an impersonator.</li>
<li>Known by others.</li>
</ul>
</p>
<p>So the only way to do passwords right is by inventing a secure (ie. hard to guess) and unique (ie. different for each site) password each time.</p>
<p>Unfortunately, secure passwords are hard to come up with and even harder to remember.</p>
<p>People generally give up and begin reusing passwords between sites. The password is now no longer secret. This can lead to your identity getting stolen when sites get hacked, you get conned by a hoax site, or you sign up with an untrustworthy website.</p>
<h1>Password Solutions</h1>
<p>To help with these problems, there are a bunch of apps available that remember your passwords for you. They accomplish this by saving your passwords in an encrypted vault or by sending them off to a cloud server.</p>
<p>These approaches are very helpful, but they come with a few very <em>important</em> <strong>downsides</strong>:
<ul>
<li>Vaults need to be backed-up to avoid the risk of complete identity loss.</li>
<li>Vaults need to be kept nearby and in-sync across the your devices or you won't always be able to access the password you need.</li>
<li>Sending passwords to the cloud means handing your keys to a company.</li>
<li>When your passwords are in the cloud they may not be available when you have no Internet access.</li>
</ul>
</p>
<h1>Solving Availability</h1>
<p>Losing all your passwords or other password availability issues are frustrating and sometimes even disastrous.</p>
<p>Master Password solves this problem by being a <em>stateless</em> solution. That means that no information needs to be saved in order for the program to be able to give you your password again in the future.</p>
<p>Since Master Password doesn't save your passwords and doesn't send them anywhere, it <strong>avoids the following risks</strong>:
<ul>
<li>Your passwords cannot be found in a file or even a backup.</li>
<li>Your passwords cannot be intercepted during sync.</li>
<li>You don't need to trust a third party with your secrets.</li>
<li>You can't lose your passwords.</li>
</ul>
</p>
</div>
<div class="thumb clearfix">
@@ -318,7 +280,7 @@ passWord[i] = passChar</pre>
<footer><div class="muted content">
<p><em>Master Password is a security product and algorithm by <a href="http://www.lhunath.com" onclick="_gaq.push(['_trackPageview', '/outbound/lhunath']);">Maarten Billemont</a>, <a href="http://www.lyndir.com" onclick="_gaq.push(['_trackPageview', '/outbound/lyndir']);">Lyndir</a> (&copy; 2011-2013).</em></p>
<p><em>Master Password is a security product and algorithm by <a href="http://www.lhunath.com" onclick="_gaq.push(['_trackPageview', '/outbound/lhunath']);">Maarten Billemont</a>, <a href="http://www.lyndir.com" onclick="_gaq.push(['_trackPageview', '/outbound/lyndir']);">Lyndir</a> (&copy; 2011-2014).</em><br>Usage implies agreement with our <a href="privacy.html">privacy policy and disclaimer</a>.</p>
<p><a href="http://gorillas.lyndir.com" onclick="_gaq.push(['_trackPageview', '/outbound/gorillas']);">Gorillas</a><a href="http://deblock.lyndir.com" onclick="_gaq.push(['_trackPageview', '/outbound/deblock']);">DeBlock</a><a href="http://github.com/Lyndir" onclick="_gaq.push(['_trackPageview', '/outbound/github']);">GitHub</a><a href="http://thanks.lhunath.com" onclick="_gaq.push(['_trackPageview', '/outbound/thanks']);">Send Thanks</a></p>
</div></footer>
@@ -358,34 +320,6 @@ passWord[i] = passChar</pre>
<!-- Tender -->
<script src="https://masterpassword.tenderapp.com/tender_widget.js" type="text/javascript"></script>
<!-- AdWords -->
<script type="text/javascript">
/* <![CDATA[ */
goog_snippet_vars = function() {
var w = window;
w.google_conversion_id = 1015576061;
w.google_conversion_label = "PcXqCPPz5AIQ_euh5AM";
w.google_conversion_value = 4;
}
goog_report_conversion = function(url) {
goog_snippet_vars();
window.google_conversion_format = "3";
window.google_is_call = true;
var opt = new Object();
opt.onload_callback = function() {
if (typeof(url) != 'undefined') {
window.location = url;
}
}
var conv_handler = window['google_trackConversion'];
if (typeof(conv_handler) == 'function') {
conv_handler(opt);
}
}
/* ]]> */
</script>
<script type="text/javascript" src="http://www.googleadservices.com/pagead/conversion_async.js"></script>
</body>
</html>

View File

@@ -35,6 +35,9 @@ a .popup {
margin-right: -100px;
padding: 8px;
}
a .popup.border {
margin-bottom: 1em;
}
a:hover .popup {
display: block;
}
@@ -108,6 +111,11 @@ img.block {
margin: auto 1em;
width: 640px;
}
img.border {
background: #AAA;
border: 1px solid #333;
padding: 1px;
}
.thumb {
clear: both;
@@ -189,6 +197,8 @@ header {
background: black;
text-shadow: black 0 1px 50px;
box-shadow: 0 1px 5px #000;
transition: height 0.3s;
}
header .container {
position: relative;
@@ -267,15 +277,19 @@ header .box .maximized {
height: 80%;
}
#app header .background {
background: url('../img/shot-laptop-leaning-iphone.png') center center;
background: url('../img/shot-laptop-leaning-iphone.jpg') center center;
background-size: cover;
}
#what header,
#security header,
#algorithm header,
#support header {
height: 40%;
background: #272727;
}
#what header .background,
#security header .background,
#algorithm header .background,
#support header .background {
width: 940px;
@@ -284,6 +298,8 @@ header .box .maximized {
top: -10%;
margin-left: -470px;
}
#what header .container,
#security header .container,
#algorithm header .container,
#support header .container {
background: radial-gradient(center, ellipse cover, rgba(0,0,0,0.3) 50%,rgba(0,0,0,0.8) 100%);
@@ -321,6 +337,92 @@ header h2 {
font-size: 2em;
font-style: oblique;
}
header .movie {
display: none;
background: url('../img/about.png') no-repeat scroll 50% 40px/cover black;
position: relative;
width: 100%;
height: 100%;
padding-top: 40px;
}
header .movie::after {
display: block;
content: " ";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('../img/loading-spin.svg') no-repeat scroll center center transparent;
}
header.play {
height: auto !important;
max-height: 94%;
}
header.play .movie {
display: block;
}
header.play .movie video {
position: relative;
z-index: 3;
}
header.play h1, header.play h2, header.play .box {
display: none;
}
header .moviecontrol {
display: block;
position: absolute;
z-index: 9;
top: 50%;
left: 50%;
margin-top: -.5em;
margin-left: -.5em;
font-size: 400%;
vertical-align: middle;
}
header .moviecontrol::before {
content: "▶";
}
header .moviecontrol:hover {
text-decoration: none;
}
header.play .moviecontrol {
right: 1em;
bottom: 1em;
left: auto;
top: auto;
}
header.play .moviecontrol::before {
content: "❙❙";
}
header .movie::before {
display: block;
content: " ";
position: absolute;
z-index: 4;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('../img/video-pattern.png') repeat;
background: url('../img/video-bg.png') no-repeat scroll 50% 100%/cover transparent;
}
header .movie video {
width: 100%;
height: 100%;
height: calc(100% - 40px);
height: auto;
}
header .movie .fallback {
position: absolute;
left: 0;
right: 0;
bottom: 60px;
text-align: center;
z-index: 5;
color: #BBB;
}
footer {
overflow: hidden;
text-align: center;
@@ -392,3 +494,29 @@ table .box.green {
background: #6A6;
border: 1px solid #3C3;
}
@media (max-width: 979px) {
.content {
width: auto;
}
header .content {
left: 0;
right: 0;
margin: 0;
padding: 20px;
}
.pull-right, .pull-left {
float: none;
}
}
@media (max-width: 767px) {
header h1 {
font-size: 4em;
}
header h2 {
font-size: 2em;
}
header .moviecontrol {
top: 1em;
}
}

View File

@@ -14,7 +14,7 @@
<link rel="shortcut icon" href="img/favicon.png" type="image/x-png" />
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-responsive.min.css">
<link rel="stylesheet" href="css/main.css?1">
<link rel="stylesheet" href="css/main.css?7">
<script src="js/vendor/modernizr-2.6.2.min.js"></script>
<script src="js/vendor/prefixfree.min.js"></script>
@@ -35,18 +35,16 @@
<a class="brand" href="./">●●●|</a>
<div class="nav-collapse collapse">
<ul class="nav">
<li><a href="./">App</a></li>
<li><a href="security.html">Security</a></li>
<li class="active"><a href="faq.html">FAQ</a></li>
<li><a href="algorithm.html">Algorithm</a></li>
<li><a href="support.html">Support</a></li>
<li><a href="http://github.com/Lyndir/MasterPassword/" onclick="_gaq.push(['_trackPageview', '/outbound/github']);">Source (GPL)</a></li>
<li><a href="what.html">What is it? How do I use it?</a></li>
<li><a href="security.html">Is it safe?</a></li>
<li><a href="algorithm.html">How does it work?</a></li>
</ul>
<ul class="nav pull-right">
<li><a href="irc://irc.freenode.net/#masterpassword" onclick="_gaq.push(['_trackPageview', '/outbound/irc']);">#masterpassword (freenode)</a></li>
<li><a href="irc://irc.freenode.net/#masterpassword" onclick="_gaq.push(['_trackPageview', '/outbound/irc']);">#masterpassword</a></li>
<li class="divider-vertical"></li>
<li><a href="MasterPassword_PressKit.zip" onclick="_gaq.push(['_trackPageview', '/outbound/presskit']);">⬇ Press Kit</a></li>
<li><a href="http://itunes.apple.com/app/id510296984" onclick="goog_report_conversion('index-fixed-header');_gaq.push(['_trackPageview', '/outbound/itunes']);" class="img"><img src="img/appstore.svg" /></a></li>
<li class="active"><a href="faq.html">FAQ</a></li>
<li><a href="support.html">Support</a></li>
<li><a href="http://github.com/Lyndir/MasterPassword/" onclick="_gaq.push(['_trackPageview', '/outbound/github']);">Source</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
@@ -228,7 +226,7 @@
<footer><div class="muted content">
<p><em>Master Password is a security product and algorithm by <a href="http://www.lhunath.com" onclick="_gaq.push(['_trackPageview', '/outbound/lhunath']);">Maarten Billemont</a>, <a href="http://www.lyndir.com" onclick="_gaq.push(['_trackPageview', '/outbound/lyndir']);">Lyndir</a> (&copy; 2011-2013).</em></p>
<p><em>Master Password is a security product and algorithm by <a href="http://www.lhunath.com" onclick="_gaq.push(['_trackPageview', '/outbound/lhunath']);">Maarten Billemont</a>, <a href="http://www.lyndir.com" onclick="_gaq.push(['_trackPageview', '/outbound/lyndir']);">Lyndir</a> (&copy; 2011-2014).</em><br>Usage implies agreement with our <a href="privacy.html">privacy policy and disclaimer</a>.</p>
<p><a href="http://gorillas.lyndir.com" onclick="_gaq.push(['_trackPageview', '/outbound/gorillas']);">Gorillas</a><a href="http://deblock.lyndir.com" onclick="_gaq.push(['_trackPageview', '/outbound/deblock']);">DeBlock</a><a href="http://github.com/Lyndir" onclick="_gaq.push(['_trackPageview', '/outbound/github']);">GitHub</a><a href="http://thanks.lhunath.com" onclick="_gaq.push(['_trackPageview', '/outbound/thanks']);">Send Thanks</a></p>
</div></footer>
@@ -268,34 +266,6 @@
<!-- Tender -->
<script src="https://masterpassword.tenderapp.com/tender_widget.js" type="text/javascript"></script>
<!-- AdWords -->
<script type="text/javascript">
/* <![CDATA[ */
goog_snippet_vars = function() {
var w = window;
w.google_conversion_id = 1015576061;
w.google_conversion_label = "PcXqCPPz5AIQ_euh5AM";
w.google_conversion_value = 4;
}
goog_report_conversion = function(url) {
goog_snippet_vars();
window.google_conversion_format = "3";
window.google_is_call = true;
var opt = new Object();
opt.onload_callback = function() {
if (typeof(url) != 'undefined') {
window.location = url;
}
}
var conv_handler = window['google_trackConversion'];
if (typeof(conv_handler) == 'function') {
conv_handler(opt);
}
}
/* ]]> */
</script>
<script type="text/javascript" src="http://www.googleadservices.com/pagead/conversion_async.js"></script>
</body>
</html>

BIN
Site/2013-05/img/about.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 KiB

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 KiB

After

Width:  |  Height:  |  Size: 284 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
Site/2013-05/img/glyphicons-halflings-white.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

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