2
0

Saved passwords login.

[FIXED]     Some crashes.
[ADDED]     Support for saved passwords login.
This commit is contained in:
Maarten Billemont 2014-06-01 22:45:29 -04:00
parent da7abf1030
commit c8eb2fdde7
12 changed files with 171 additions and 83 deletions

2
External/Pearl vendored

@ -1 +1 @@
Subproject commit 0e9484b6512150fbbfffdddcdec62f8e9a741254
Subproject commit daa260b3ecaca266ffcfa597e9350900dda6cc56

View File

@ -15,13 +15,13 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.1.9</string>
<string>2.2.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string>
</array>
<key>CFBundleVersion</key>
<string>31</string>
<string>33</string>
<key>DTPlatformName</key>
<string>iphoneos</string>
<key>MinimumOSVersion</key>

Binary file not shown.

BIN
External/iOS/Crashlytics.framework/submit vendored Executable file

Binary file not shown.

View File

@ -107,13 +107,11 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
}
// Method 3: Check the given master password string.
if (!tryKey) {
if ([password length]) if ((tryKey = [MPAlgorithmDefault keyForPassword:password
ofUserNamed:user.name])) if (![user.keyID isEqual:tryKey.keyID]) {
inf( @"Key derived from password doesn't match keyID for: %@", user.userID );
if (!tryKey && [password length] && (tryKey = [MPAlgorithmDefault keyForPassword:password ofUserNamed:user.name]) &&
![user.keyID isEqual:tryKey.keyID]) {
inf( @"Key derived from password doesn't match keyID for: %@", user.userID );
tryKey = nil;
}
tryKey = nil;
}
// No more methods left, fail if key still not known.

View File

@ -30,6 +30,8 @@
+ (instancetype)dequeueCellWithType:(MPElementType)type fromCollectionView:(UICollectionView *)collectionView
atIndexPath:(NSIndexPath *)indexPath {
NSAssert(type != 0 && type != (MPElementType)NSNotFound, @"Cannot dequeue a password cell without a type.");
NSString *reuseIdentifier;
if (type & MPElementTypeClassGenerated)
reuseIdentifier = NSStringFromClass( [MPPasswordLargeGeneratedCell class] );
@ -163,6 +165,13 @@
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
UICollectionView *collectionView = [UICollectionView findAsSuperviewOf:self];
[collectionView scrollToItemAtIndexPath:[collectionView indexPathForCell:self]
atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if (textField == self.contentField) {

View File

@ -21,4 +21,5 @@
@interface MPPasswordLargeDeleteCell : MPPasswordLargeCell
+ (MPPasswordLargeCell *)dequeueCellFromCollectionView:(UICollectionView *)view atIndexPath:(NSIndexPath *)path;
@end

View File

@ -1,12 +1,12 @@
/**
* 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
*/
* 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
*/
//
// MPPasswordLargeDeleteCell.h
@ -22,6 +22,15 @@
#pragma mark - Lifecycle
+ (MPPasswordLargeCell *)dequeueCellFromCollectionView:(UICollectionView *)collectionView atIndexPath:(NSIndexPath *)indexPath {
MPPasswordLargeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass( [self class] )
forIndexPath:indexPath];
cell.type = (MPElementType)NSNotFound;
return cell;
}
- (MPElementEntity *)saveContentTypeWithElement:(MPElementEntity *)element saveInContext:(NSManagedObjectContext *)context {
return element;

View File

@ -87,30 +87,32 @@
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (!self.algorithm)
dbg_return_tr( 0, @, @(section) );
return 0;
if (self.transientSite)
dbg_return_tr( [[self.algorithm allTypes] count], @, @(section) );
return [[self.algorithm allTypes] count];
dbg_return_tr( [[self.algorithm allTypes] count] + 1 /* Delete */, @, @(section) );
return [[self.algorithm allTypes] count] + 1 /* Delete */;
}
- (MPPasswordLargeCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MPPasswordLargeCell *cell;
if (indexPath.item == 0)
cell = [MPPasswordLargeDeleteCell dequeueCellWithType:(MPElementType)NSNotFound fromCollectionView:collectionView
atIndexPath:indexPath];
cell = [MPPasswordLargeDeleteCell dequeueCellFromCollectionView:collectionView atIndexPath:indexPath];
else
cell = [MPPasswordLargeCell dequeueCellWithType:[self typeForContentIndexPath:indexPath] fromCollectionView:collectionView
atIndexPath:indexPath];
[cell prepareForReuse];
if (self.transientSite)
[cell updateWithTransientSite:self.transientSite];
else
[cell updateWithElement:self.mainElement];
dbg( @"cell %d, contentFieldMode: %d", indexPath.item, cell.contentFieldMode );
dbg_return( cell, indexPath );
return cell;
}
#pragma mark - UICollectionViewDelegateFlowLayout

View File

@ -129,7 +129,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) {
break;
}
case MPActiveUserStateLogin: {
[self.entryField endEditing:YES];
self.entryField.enabled = NO;
[self selectedAvatar].spinnerActive = YES;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
BOOL signedIn = NO, isNew = NO;
@ -140,6 +140,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.entryField.text = @"";
self.entryField.enabled = YES;
[self selectedAvatar].spinnerActive = NO;
if (!signedIn) {
@ -189,7 +190,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) {
return NO;
}
[self.entryField endEditing:YES];
self.entryField.enabled = NO;
MPAvatarCell *avatarCell = [self selectedAvatar];
avatarCell.spinnerActive = YES;
if (![MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
@ -204,6 +205,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) {
BOOL signedIn = [[MPiOSAppDelegate get] signInAsUser:user saveInContext:context usingMasterPassword:masterPassword];
PearlMainQueue( ^{
self.entryField.text = @"";
self.entryField.enabled = YES;
[self selectedAvatar].spinnerActive = NO;
if (!signedIn) {
@ -315,15 +317,29 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) {
}
BOOL isNew = NO;
MPUserEntity *user = [self userForIndexPath:indexPath inContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]
isNew:&isNew];
NSManagedObjectContext *mainContext = [MPiOSAppDelegate managedObjectContextForMainThreadIfReady];
MPUserEntity *mainUser = [self userForIndexPath:indexPath inContext:mainContext isNew:&isNew];
if (isNew)
self.activeUserState = MPActiveUserStateUserName;
else if (!user.keyID)
else if (!mainUser.keyID)
self.activeUserState = MPActiveUserStateMasterPasswordChoice;
else
else {
self.activeUserState = MPActiveUserStateLogin;
self.entryField.enabled = NO;
[self selectedAvatar].spinnerActive = YES;
BOOL signedIn = NO;
if (!isNew && mainUser)
signedIn = [[MPiOSAppDelegate get] signInAsUser:mainUser saveInContext:mainContext usingMasterPassword:nil];
self.entryField.text = @"";
self.entryField.enabled = YES;
[self selectedAvatar].spinnerActive = NO;
if (!signedIn)
[self.entryField becomeFirstResponder];
}
}
}

View File

@ -16,19 +16,19 @@
<viewControllerLayoutGuide type="bottom" id="VGz-R0-vMD"/>
</layoutGuides>
<view key="view" clipsSubviews="YES" contentMode="scaleToFill" id="DOr-Xu-P9q" userLabel="Root">
<rect key="frame" x="0.0" y="0.0" width="320" height="504"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="548"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rWM-08-aab" userLabel="Users Root">
<rect key="frame" x="0.0" y="0.0" width="320" height="504"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="548"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="VDd-oM-ZOO" userLabel="Store Activity">
<rect key="frame" x="142" y="234" width="37" height="37"/>
<rect key="frame" x="142" y="256" width="37" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</activityIndicatorView>
<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" alpha="0.0" contentMode="scaleToFill" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="L6J-pd-gcp" userLabel="Avatar Collection">
<rect key="frame" x="0.0" y="20" width="320" height="484"/>
<rect key="frame" x="0.0" y="20" width="320" height="528"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="ATB-kM-EGu">
@ -39,7 +39,7 @@
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPAvatarCell" id="Zab-uQ-uk9" customClass="MPAvatarCell">
<rect key="frame" x="80" y="0.0" width="160" height="484"/>
<rect key="frame" x="80" y="22" width="160" height="484"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<userGuides>
<userLayoutGuide location="210" affinity="minY"/>
@ -110,11 +110,11 @@
</collectionViewCell>
</cells>
<collectionReusableView key="sectionHeaderView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPAvatarIndent" id="LD1-mt-htC">
<rect key="frame" x="0.0" y="0.0" width="80" height="484"/>
<rect key="frame" x="0.0" y="0.0" width="80" height="528"/>
<autoresizingMask key="autoresizingMask"/>
</collectionReusableView>
<collectionReusableView key="sectionFooterView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPAvatarOutdent" id="G8v-Sb-ilL">
<rect key="frame" x="240" y="0.0" width="80" height="484"/>
<rect key="frame" x="240" y="0.0" width="80" height="528"/>
<autoresizingMask key="autoresizingMask"/>
</collectionReusableView>
<connections>
@ -123,7 +123,7 @@
</connections>
</collectionView>
<button opaque="NO" alpha="0.69999999999999996" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9u7-pu-Wtv" userLabel="Previous Avatar">
<rect key="frame" x="0.0" y="127" width="44" height="53"/>
<rect key="frame" x="0.0" y="171" width="44" height="53"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<constraints>
<constraint firstAttribute="width" constant="44" id="Ay6-Jg-c3T"/>
@ -137,7 +137,7 @@
</connections>
</button>
<button opaque="NO" alpha="0.69999999999999996" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fUK-gJ-NRE" userLabel="Next Avatar">
<rect key="frame" x="276" y="127" width="44" height="53"/>
<rect key="frame" x="276" y="171" width="44" height="53"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<constraints>
<constraint firstAttribute="width" constant="44" id="oAm-YX-Fx5"/>
@ -151,7 +151,7 @@
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qp1-nX-o4i" userLabel="Entry" customClass="PearlUIView">
<rect key="frame" x="20" y="216" width="280" height="63"/>
<rect key="frame" x="20" y="260" width="280" height="63"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Enter your full name:" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="5fe-rt-zFa" userLabel="Entry Label">
@ -237,7 +237,7 @@
</userDefinedRuntimeAttributes>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XEP-O3-ayG" userLabel="Footer" customClass="PearlUIView">
<rect key="frame" x="0.0" y="433" width="320" height="71"/>
<rect key="frame" x="0.0" y="477" width="320" height="71"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" alpha="0.5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4md-Gp-SLG">
@ -350,7 +350,7 @@
</connections>
</searchDisplayController>
</objects>
<point key="canvasLocation" x="1355" y="496"/>
<point key="canvasLocation" x="1355" y="474"/>
</scene>
<!--Web View Controller-->
<scene sceneID="JQz-u7-oA7">
@ -361,11 +361,11 @@
<viewControllerLayoutGuide type="bottom" id="Eo0-ai-7DG"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="2Jz-8H-3nG" userLabel="Root">
<rect key="frame" x="0.0" y="0.0" width="320" height="504"/>
<rect key="frame" x="0.0" y="0.0" width="320" height="548"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<webView contentMode="scaleToFill" scalesPageToFit="YES" suppressesIncrementalRendering="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3aB-Hk-Fgd">
<rect key="frame" x="0.0" y="20" width="320" height="484"/>
<rect key="frame" x="0.0" y="20" width="320" height="528"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<connections>
@ -397,6 +397,7 @@
<constraint firstAttribute="trailing" secondItem="3aB-Hk-Fgd" secondAttribute="trailing" id="xdJ-WF-yw0"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="gmy-ym-z4I"/>
<connections>
<outlet property="webNavigationItem" destination="Wpf-6b-UJb" id="8gM-LU-pHk"/>
<outlet property="webView" destination="3aB-Hk-Fgd" id="Mie-rI-l4h"/>
@ -404,12 +405,12 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="hNt-WS-DuE" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1887" y="496"/>
<point key="canvasLocation" x="813" y="-272"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="bzn-yi-kMJ">
<objects>
<navigationController definesPresentationContext="YES" id="Q1S-vU-GGO" sceneMemberID="viewController">
<navigationController definesPresentationContext="YES" navigationBarHidden="YES" id="Q1S-vU-GGO" sceneMemberID="viewController">
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="4yl-zs-iUd">
<autoresizingMask key="autoresizingMask"/>
@ -417,6 +418,7 @@
<connections>
<segue destination="Ac5-na-hOV" kind="relationship" relationship="rootViewController" id="7h0-mv-UM6"/>
<segue destination="Ec4-G7-5Td" kind="modal" identifier="setup" id="CsD-w4-Lhp"/>
<segue destination="Sd5-eW-Cx2" kind="modal" identifier="web" id="GZk-I4-JyH"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="OhM-cb-bMF" userLabel="First Responder" sceneMemberID="firstResponder"/>
@ -440,7 +442,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<containerView clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jDK-5y-QRP" userLabel="Users">
<rect key="frame" x="0.0" y="64" width="320" height="504"/>
<rect key="frame" x="0.0" y="20" width="320" height="548"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<connections>
<segue destination="S8q-YF-Kt9" kind="embed" identifier="users" id="9AR-TX-BkY"/>
@ -459,6 +461,7 @@
</constraints>
</view>
<navigationItem key="navigationItem" id="MPa-zX-Kaq"/>
<nil key="simulatedTopBarMetrics"/>
<connections>
<outlet property="usersView" destination="jDK-5y-QRP" id="cuP-gN-eBE"/>
<segue destination="osn-5H-SWW" kind="custom" identifier="emergency" customClass="MPEmergencySegue" id="gtX-Cx-AA2"/>
@ -692,7 +695,7 @@
<rect key="frame" x="136" y="178" width="51" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<connections>
<action selector="didToggleSwitch:" destination="JFc-sj-awD" eventType="valueChanged" id="byF-3g-DmH"/>
<action selector="valueChanged:" destination="JFc-sj-awD" eventType="valueChanged" id="KMj-5x-BcK"/>
</connections>
</switch>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Save Password" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3fk-Io-xQI">
@ -1721,7 +1724,7 @@
</connections>
</tapGestureRecognizer>
</objects>
<point key="canvasLocation" x="1350" y="-264"/>
<point key="canvasLocation" x="1350" y="-272"/>
</scene>
<!--App Settings View Controller - Settings-->
<scene sceneID="fmc-CS-nuo">
@ -1774,7 +1777,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="fiE-U7-p6y" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2778" y="2672"/>
<point key="canvasLocation" x="2866" y="464"/>
</scene>
<!--View Controller-->
<scene sceneID="qiQ-By-IQy">
@ -1792,7 +1795,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="OKk-Ht-Uzq" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2778" y="1936"/>
<point key="canvasLocation" x="2866" y="-272"/>
</scene>
<!--Logs View Controller - Logbook-->
<scene sceneID="cks-mO-kuy">
@ -1942,22 +1945,47 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Enable iCloud?" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eC1-NU-fVL">
<rect key="frame" x="20" y="108" width="280" height="21"/>
<rect key="frame" x="20" y="108" width="277" height="21"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="280" translatesAutoresizingMaskIntoConstraints="NO" id="tco-oc-EfM">
<rect key="frame" x="20" y="137" width="280" height="268"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="277" translatesAutoresizingMaskIntoConstraints="NO" id="tco-oc-EfM">
<rect key="frame" x="20" y="137" width="277" height="262"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<string key="text">Enabling iCloud will keep all your iPhones, iPads and Macs nicely in-sync. Any site you add on this device will automatically appear on all your others as well.
<attributedString key="attributedText">
<fragment>
<string key="content">Enabling iCloud will keep all your iPhones, iPads and Macs nicely in-sync. Any site you add on this device will automatically appear on all your others as well.
Note that even without iCloud syncing, you can make your passwords available from any device by simply creating the same user on all your devices. Enabling iCloud is mainly benefitial to keep the list of sites you use in sync on all your devices.
</string>
<attributes>
<color key="NSBackgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
<fragment content="Note: some people have reported iCloud can be unreliable">
<attributes>
<color key="NSBackgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="HelveticaNeue-Bold"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
<fragment>
<string key="content">. Even without iCloud your generated passwords will be available from any device you add your user to. iCloud mainly serves to keep the list of sites you use updated across devices.
Only site names and custom passwords are sent to iCloud. Passwords are encrypted with your master password and illegible by Apple or any interceptor.</string>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
Only site names and personal passwords are sent to iCloud. Passwords are encrypted with your master password and unreadable by anyone else.</string>
<attributes>
<color key="NSBackgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
</attributedString>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="adu-Cl-cW3">
@ -2385,32 +2413,32 @@ However, it means that anyone who finds your device unlocked can do the same.</s
<action selector="close:" destination="a4U-1y-he6" eventType="touchUpInside" id="dLv-Dh-bHi"/>
</connections>
</button>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Tap for user preferences" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3eY-lZ-dPZ">
<rect key="frame" x="66" y="32" width="188" height="21"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Preferences and Sign Out" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3eY-lZ-dPZ">
<rect key="frame" x="63" y="32" width="194" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Enter your site name" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SCn-dQ-xrj">
<rect key="frame" x="81" y="76" width="159" height="21"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Enter your site's name" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SCn-dQ-xrj">
<rect key="frame" x="75" y="76" width="171" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Tap to copy the site's password" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ScF-Yu-oFB">
<rect key="frame" x="61" y="120" width="199" height="17"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Tap to copy the site password" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ScF-Yu-oFB">
<rect key="frame" x="66" y="120" width="189" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="right" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="182" translatesAutoresizingMaskIntoConstraints="NO" id="0Qe-Pv-mvu">
<rect key="frame" x="38" y="175" width="182" height="34"/>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="right" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="196" translatesAutoresizingMaskIntoConstraints="NO" id="0Qe-Pv-mvu">
<rect key="frame" x="24" y="175" width="196" height="34"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<string key="text">Password counter:
Tap it to get a new password</string>
Tap it to make a new password</string>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
@ -2531,7 +2559,7 @@ to change type or delete them</string>
</label>
<placeholder placeholderIdentifier="IBFirstResponder" id="Qy9-t1-6gT" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1350" y="1936"/>
<point key="canvasLocation" x="1887" y="1936"/>
</scene>
<!--Setup View Controller - About-->
<scene sceneID="p3O-pB-vAg">
@ -2565,14 +2593,14 @@ to change type or delete them</string>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" usesAttributedText="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" preferredMaxLayoutWidth="280" translatesAutoresizingMaskIntoConstraints="NO" id="J90-SQ-ljR">
<rect key="frame" x="20" y="137" width="280" height="387"/>
<rect key="frame" x="20" y="137" width="280" height="556"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<attributedString key="attributedText">
<fragment content="The passwords created by this app are not stored anywhere but ">
<fragment content="The passwords generated by this app are not stored but ">
<attributes>
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="Helvetica"/>
<font key="NSFont" size="14" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
@ -2580,19 +2608,20 @@ to change type or delete them</string>
<attributes>
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="Helvetica-Oblique"/>
<font key="NSFont" size="14" name="HelveticaNeue-Italic"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
<fragment>
<string key="content">.
This means your passwords are safe from loss and theft: if you ever lose your phone or user, just recreate the user with the same master password, add your sites back and their original passwords will re-appear.
This is very different from most any other password app: when your passwords are not stored, they are safe from loss and theft if you lose your phone or user. On your new phone, just recreate the user with the same master password and your sites will generate their original passwords again. The cryptography used by this app is also much stronger than that used by most other password applications.
You don't need to remember any password generated by this app, but </string>
<attributes>
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="Helvetica"/>
<font key="NSFont" size="14" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
@ -2600,7 +2629,7 @@ You don't need to remember any password generated by this app, but </string>
<attributes>
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="Helvetica-Bold"/>
<font key="NSFont" size="14" name="HelveticaNeue-Bold"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
@ -2608,20 +2637,22 @@ You don't need to remember any password generated by this app, but </string>
<attributes>
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="Helvetica-BoldOblique"/>
<font key="NSFont" size="14" name="HelveticaNeue-BoldItalic"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
<fragment>
<string key="content"> and that it is secure.
Don't reuse an old password!
Never give out your master password; not even to family. Share site passwords instead.
A small sentence is a great password. </string>
Don't reuse an old password!
Never share your master password; not even with family.
Share your sites password instead.
A small sentence is a great password.
</string>
<attributes>
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="Helvetica"/>
<font key="NSFont" size="14" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
@ -2629,18 +2660,37 @@ A small sentence is a great password. </string>
<attributes>
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="Helvetica-Bold"/>
<font key="NSFont" size="14" name="HelveticaNeue-Bold"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
<fragment>
<string key="content">
You can make passwords for anything, like email addresses, sites or real-world things like a bike lock: if you can name it, you can get a password for it.</string>
You can make passwords for anything, like email addresses, sites or real-world things like a bike lock: if you can name it, you can get a password for it.
See </string>
<attributes>
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="Helvetica"/>
<font key="NSFont" size="14" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
<fragment content="http://masterpasswordapp.com/security.html">
<attributes>
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="HelveticaNeue"/>
<url key="NSLink" string="http://masterpasswordapp.com/security.html"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
<fragment content=" for information on the security properties of this app.">
<attributes>
<color key="NSBackgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="NSColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<font key="NSFont" size="14" name="HelveticaNeue"/>
<paragraphStyle key="NSParagraphStyle" alignment="left" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
@ -2712,4 +2762,7 @@ You can make passwords for anything, like email addresses, sites or real-world t
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
<inferredMetricsTieBreakers>
<segue reference="gtb-zE-u9H"/>
</inferredMetricsTieBreakers>
</document>