diff --git a/External/Pearl b/External/Pearl index e93f7c40..0a5a01b8 160000 --- a/External/Pearl +++ b/External/Pearl @@ -1 +1 @@ -Subproject commit e93f7c406b157df3a4538becd2bff8b9ee7b0be8 +Subproject commit 0a5a01b8862a3e8d986b23513c5d40ebc152b6fc diff --git a/MasterPassword-iOS.xcodeproj/project.pbxproj b/MasterPassword-iOS.xcodeproj/project.pbxproj index cdd4e92e..04901f48 100644 --- a/MasterPassword-iOS.xcodeproj/project.pbxproj +++ b/MasterPassword-iOS.xcodeproj/project.pbxproj @@ -8,10 +8,6 @@ /* Begin PBXBuildFile section */ DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */; }; - DA076C75157D58E5008968D7 /* MPElementGeneratedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA076C74157D58E5008968D7 /* MPElementGeneratedEntity.m */; }; - DA076C78157D58E5008968D7 /* MPElementEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA076C77157D58E5008968D7 /* MPElementEntity.m */; }; - DA076C7B157D58E5008968D7 /* MPElementStoredEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA076C7A157D58E5008968D7 /* MPElementStoredEntity.m */; }; - DA076C7E157D58E6008968D7 /* MPUserEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA076C7D157D58E6008968D7 /* MPUserEntity.m */; }; DA0A1D0515690A9A0092735D /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = DA0A1D0315690A9A0092735D /* Default.png */; }; DA0A1D0615690A9A0092735D /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA0A1D0415690A9A0092735D /* Default@2x.png */; }; DA0A1D1515690AF40092735D /* Icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA0A1D1315690AF30092735D /* Icon-72@2x.png */; }; @@ -24,6 +20,10 @@ DA30E9D415722EF400A68B4C /* Pearl-UIKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */; }; DA30E9D715723E6900A68B4C /* PearlLazy.h in Headers */ = {isa = PBXBuildFile; fileRef = DA30E9D515723E6900A68B4C /* PearlLazy.h */; }; DA30E9D815723E6900A68B4C /* PearlLazy.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30E9D615723E6900A68B4C /* PearlLazy.m */; }; + DA40C2611586099D0079CE6E /* MPUserEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA40C2601586099D0079CE6E /* MPUserEntity.m */; }; + DA40C2641586099E0079CE6E /* MPElementEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA40C2631586099E0079CE6E /* MPElementEntity.m */; }; + DA40C2671586099E0079CE6E /* MPElementGeneratedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA40C2661586099E0079CE6E /* MPElementGeneratedEntity.m */; }; + DA40C26A1586099E0079CE6E /* MPElementStoredEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA40C2691586099E0079CE6E /* MPElementStoredEntity.m */; }; DA4425CC1557BED40052177D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; DA4426001557BF260052177D /* UbiquityStoreManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DA4425F11557BF260052177D /* UbiquityStoreManager.h */; }; DA4426011557BF260052177D /* UbiquityStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4425F21557BF260052177D /* UbiquityStoreManager.m */; }; @@ -908,14 +908,6 @@ /* Begin PBXFileReference section */ DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; - DA076C73157D58E5008968D7 /* MPElementGeneratedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementGeneratedEntity.h; sourceTree = ""; }; - DA076C74157D58E5008968D7 /* MPElementGeneratedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementGeneratedEntity.m; sourceTree = ""; }; - DA076C76157D58E5008968D7 /* MPElementEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementEntity.h; sourceTree = ""; }; - DA076C77157D58E5008968D7 /* MPElementEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementEntity.m; sourceTree = ""; }; - DA076C79157D58E5008968D7 /* MPElementStoredEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementStoredEntity.h; sourceTree = ""; }; - DA076C7A157D58E5008968D7 /* MPElementStoredEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementStoredEntity.m; sourceTree = ""; }; - DA076C7C157D58E6008968D7 /* MPUserEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUserEntity.h; sourceTree = ""; }; - DA076C7D157D58E6008968D7 /* MPUserEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUserEntity.m; sourceTree = ""; }; DA0A1D0315690A9A0092735D /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = Resources/Default.png; sourceTree = SOURCE_ROOT; }; DA0A1D0415690A9A0092735D /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "Resources/Default@2x.png"; sourceTree = SOURCE_ROOT; }; DA0A1D0715690AD40092735D /* tip_arrow_banana.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tip_arrow_banana.png; path = Resources/Tooltips/tip_arrow_banana.png; sourceTree = SOURCE_ROOT; }; @@ -935,6 +927,14 @@ DA30E9D315722EF400A68B4C /* Pearl-UIKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Pearl-UIKit.m"; sourceTree = ""; }; DA30E9D515723E6900A68B4C /* PearlLazy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlLazy.h; sourceTree = ""; }; DA30E9D615723E6900A68B4C /* PearlLazy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlLazy.m; sourceTree = ""; }; + DA40C25F1586099D0079CE6E /* MPUserEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUserEntity.h; sourceTree = ""; }; + DA40C2601586099D0079CE6E /* MPUserEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUserEntity.m; sourceTree = ""; }; + DA40C2621586099E0079CE6E /* MPElementEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementEntity.h; sourceTree = ""; }; + DA40C2631586099E0079CE6E /* MPElementEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementEntity.m; sourceTree = ""; }; + DA40C2651586099E0079CE6E /* MPElementGeneratedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementGeneratedEntity.h; sourceTree = ""; }; + DA40C2661586099E0079CE6E /* MPElementGeneratedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementGeneratedEntity.m; sourceTree = ""; }; + DA40C2681586099E0079CE6E /* MPElementStoredEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementStoredEntity.h; sourceTree = ""; }; + DA40C2691586099E0079CE6E /* MPElementStoredEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementStoredEntity.m; sourceTree = ""; }; DA4425CB1557BED40052177D /* libiCloudStoreManager.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libiCloudStoreManager.a; sourceTree = BUILT_PRODUCTS_DIR; }; DA4425F11557BF260052177D /* UbiquityStoreManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UbiquityStoreManager.h; sourceTree = ""; }; DA4425F21557BF260052177D /* UbiquityStoreManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UbiquityStoreManager.m; sourceTree = ""; }; @@ -1968,17 +1968,17 @@ DA5BFA50147E415C00F98B1E /* MasterPassword */ = { isa = PBXGroup; children = ( - DAB8D43C15036BCF00CED3BC /* MasterPassword.xcdatamodeld */, - DA076C7C157D58E6008968D7 /* MPUserEntity.h */, - DA076C7D157D58E6008968D7 /* MPUserEntity.m */, - DA076C79157D58E5008968D7 /* MPElementStoredEntity.h */, - DA076C7A157D58E5008968D7 /* MPElementStoredEntity.m */, - DA076C76157D58E5008968D7 /* MPElementEntity.h */, - DA076C77157D58E5008968D7 /* MPElementEntity.m */, - DA076C73157D58E5008968D7 /* MPElementGeneratedEntity.h */, - DA076C74157D58E5008968D7 /* MPElementGeneratedEntity.m */, + DA40C2681586099E0079CE6E /* MPElementStoredEntity.h */, + DA40C2691586099E0079CE6E /* MPElementStoredEntity.m */, + DA40C2651586099E0079CE6E /* MPElementGeneratedEntity.h */, + DA40C2661586099E0079CE6E /* MPElementGeneratedEntity.m */, + DA40C2621586099E0079CE6E /* MPElementEntity.h */, + DA40C2631586099E0079CE6E /* MPElementEntity.m */, + DA40C25F1586099D0079CE6E /* MPUserEntity.h */, + DA40C2601586099D0079CE6E /* MPUserEntity.m */, DA0E07941577FE490008A67E /* MPEntities.h */, DA0E07951577FE490008A67E /* MPEntities.m */, + DAB8D43C15036BCF00CED3BC /* MasterPassword.xcdatamodeld */, DA600C2415054F3A008E9AB6 /* MPAppDelegate_Key.h */, DA600C2315054F3A008E9AB6 /* MPAppDelegate_Key.m */, DA4426041557C1990052177D /* MPAppDelegate_Shared.h */, @@ -4171,10 +4171,10 @@ DA4426091557C1990052177D /* MPAppDelegate_Store.m in Sources */, DA0E07961577FE490008A67E /* MPEntities.m in Sources */, DAC728CA157C247B00889EF2 /* MPPreferencesViewController.m in Sources */, - DA076C75157D58E5008968D7 /* MPElementGeneratedEntity.m in Sources */, - DA076C78157D58E5008968D7 /* MPElementEntity.m in Sources */, - DA076C7B157D58E5008968D7 /* MPElementStoredEntity.m in Sources */, - DA076C7E157D58E6008968D7 /* MPUserEntity.m in Sources */, + DA40C2611586099D0079CE6E /* MPUserEntity.m in Sources */, + DA40C2641586099E0079CE6E /* MPElementEntity.m in Sources */, + DA40C2671586099E0079CE6E /* MPElementGeneratedEntity.m in Sources */, + DA40C26A1586099E0079CE6E /* MPElementStoredEntity.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/MasterPassword/MPElementEntity.h b/MasterPassword/MPElementEntity.h index 9f69efd1..f4d8251f 100644 --- a/MasterPassword/MPElementEntity.h +++ b/MasterPassword/MPElementEntity.h @@ -2,7 +2,7 @@ // MPElementEntity.h // MasterPassword-iOS // -// Created by Maarten Billemont on 04/06/12. +// Created by Maarten Billemont on 11/06/12. // Copyright (c) 2012 Lyndir. All rights reserved. // @@ -14,10 +14,10 @@ @interface MPElementEntity : NSManagedObject @property (nonatomic, retain) id content; -@property (nonatomic, retain) NSDate *lastUsed; -@property (nonatomic, retain) NSString *name; -@property (nonatomic, retain) NSNumber *type_; -@property (nonatomic, retain) NSNumber *uses_; +@property (nonatomic, retain) NSDate * lastUsed; +@property (nonatomic, retain) NSString * name; +@property (nonatomic, retain) NSNumber * type_; +@property (nonatomic, retain) NSNumber * uses_; @property (nonatomic, retain) MPUserEntity *user; @end diff --git a/MasterPassword/MPElementEntity.m b/MasterPassword/MPElementEntity.m index ca332060..56bfd174 100644 --- a/MasterPassword/MPElementEntity.m +++ b/MasterPassword/MPElementEntity.m @@ -2,11 +2,12 @@ // MPElementEntity.m // MasterPassword-iOS // -// Created by Maarten Billemont on 04/06/12. +// Created by Maarten Billemont on 11/06/12. // Copyright (c) 2012 Lyndir. All rights reserved. // #import "MPElementEntity.h" +#import "MPUserEntity.h" @implementation MPElementEntity diff --git a/MasterPassword/MPElementGeneratedEntity.h b/MasterPassword/MPElementGeneratedEntity.h index 68a793a7..d31c2dea 100644 --- a/MasterPassword/MPElementGeneratedEntity.h +++ b/MasterPassword/MPElementGeneratedEntity.h @@ -2,7 +2,7 @@ // MPElementGeneratedEntity.h // MasterPassword-iOS // -// Created by Maarten Billemont on 04/06/12. +// Created by Maarten Billemont on 11/06/12. // Copyright (c) 2012 Lyndir. All rights reserved. // @@ -13,6 +13,6 @@ @interface MPElementGeneratedEntity : MPElementEntity -@property (nonatomic, retain) NSNumber *counter_; +@property (nonatomic, retain) NSNumber * counter_; @end diff --git a/MasterPassword/MPElementGeneratedEntity.m b/MasterPassword/MPElementGeneratedEntity.m index 60de78cb..ed781a4b 100644 --- a/MasterPassword/MPElementGeneratedEntity.m +++ b/MasterPassword/MPElementGeneratedEntity.m @@ -2,7 +2,7 @@ // MPElementGeneratedEntity.m // MasterPassword-iOS // -// Created by Maarten Billemont on 04/06/12. +// Created by Maarten Billemont on 11/06/12. // Copyright (c) 2012 Lyndir. All rights reserved. // diff --git a/MasterPassword/MPElementStoredEntity.h b/MasterPassword/MPElementStoredEntity.h index ef046f04..9a5088c1 100644 --- a/MasterPassword/MPElementStoredEntity.h +++ b/MasterPassword/MPElementStoredEntity.h @@ -2,7 +2,7 @@ // MPElementStoredEntity.h // MasterPassword-iOS // -// Created by Maarten Billemont on 04/06/12. +// Created by Maarten Billemont on 11/06/12. // Copyright (c) 2012 Lyndir. All rights reserved. // diff --git a/MasterPassword/MPElementStoredEntity.m b/MasterPassword/MPElementStoredEntity.m index f34bf525..c1a94f1a 100644 --- a/MasterPassword/MPElementStoredEntity.m +++ b/MasterPassword/MPElementStoredEntity.m @@ -2,7 +2,7 @@ // MPElementStoredEntity.m // MasterPassword-iOS // -// Created by Maarten Billemont on 04/06/12. +// Created by Maarten Billemont on 11/06/12. // Copyright (c) 2012 Lyndir. All rights reserved. // diff --git a/MasterPassword/MPEntities.h b/MasterPassword/MPEntities.h index 71ed04a1..4591cd22 100644 --- a/MasterPassword/MPEntities.h +++ b/MasterPassword/MPEntities.h @@ -35,5 +35,6 @@ @property (assign) NSUInteger avatar; @property (assign) BOOL saveKey; +@property (assign) MPElementType defaultType; @end diff --git a/MasterPassword/MPEntities.m b/MasterPassword/MPEntities.m index 545be914..a66287fe 100644 --- a/MasterPassword/MPEntities.m +++ b/MasterPassword/MPEntities.m @@ -9,6 +9,7 @@ #import "MPEntities.h" #import "MPAppDelegate.h" #import "MPAppDelegate_Key.h" +#import "MPUserEntity.h" @implementation MPElementEntity (MP) @@ -17,9 +18,9 @@ return (MPElementType)[self.type_ unsignedIntegerValue]; } -- (void)setType:(MPElementType)type { +- (void)setType:(MPElementType)aType { - self.type_ = PearlUnsignedInteger(type); + self.type_ = PearlUnsignedInteger(aType); } - (NSUInteger)uses { @@ -172,4 +173,14 @@ self.saveKey_ = [NSNumber numberWithBool:aSaveKey]; } +- (MPElementType)defaultType { + + return (MPElementType)[self.defaultType_ unsignedIntegerValue]; +} + +- (void)setDefaultType:(MPElementType)aDefaultType { + + self.defaultType_ = PearlUnsignedInteger(aDefaultType); +} + @end diff --git a/MasterPassword/MPTypes.h b/MasterPassword/MPTypes.h index 8b111a78..56e8d6ca 100644 --- a/MasterPassword/MPTypes.h +++ b/MasterPassword/MPTypes.h @@ -31,17 +31,18 @@ typedef enum { } MPElementFeature; typedef enum { - MPElementTypeGeneratedSecure = 0x0 | MPElementTypeClassGenerated | 0x0, - MPElementTypeGeneratedLong = 0x1 | MPElementTypeClassGenerated | 0x0, - MPElementTypeGeneratedMedium = 0x2 | MPElementTypeClassGenerated | 0x0, - MPElementTypeGeneratedShort = 0x3 | MPElementTypeClassGenerated | 0x0, - MPElementTypeGeneratedBasic = 0x4 | MPElementTypeClassGenerated | 0x0, - MPElementTypeGeneratedPIN = 0x5 | MPElementTypeClassGenerated | 0x0, + MPElementTypeGeneratedMaximum = 0x0 | MPElementTypeClassGenerated | 0x0, + MPElementTypeGeneratedLong = 0x1 | MPElementTypeClassGenerated | 0x0, + MPElementTypeGeneratedMedium = 0x2 | MPElementTypeClassGenerated | 0x0, + MPElementTypeGeneratedShort = 0x3 | MPElementTypeClassGenerated | 0x0, + MPElementTypeGeneratedBasic = 0x4 | MPElementTypeClassGenerated | 0x0, + MPElementTypeGeneratedPIN = 0x5 | MPElementTypeClassGenerated | 0x0, MPElementTypeStoredPersonal = 0x0 | MPElementTypeClassStored | MPElementFeatureExportContent, MPElementTypeStoredDevicePrivate = 0x1 | MPElementTypeClassStored | MPElementFeatureDevicePrivate, } MPElementType; +// TODO: Review checkpoints #define MPTestFlightCheckpointAction @"MPTestFlightCheckpointAction" #define MPTestFlightCheckpointHelpChapter @"MPTestFlightCheckpointHelpChapter_%@" #define MPTestFlightCheckpointCopyToPasteboard @"MPTestFlightCheckpointCopyToPasteboard" @@ -81,6 +82,7 @@ NSData *keyForPassword(NSString *password, NSString *username); NSData *keyIDForPassword(NSString *password, NSString *username); NSData *keyIDForKey(NSData *key); NSString *NSStringFromMPElementType(MPElementType type); +NSString *NSStringShortFromMPElementType(MPElementType type); NSString *ClassNameFromMPElementType(MPElementType type); Class ClassFromMPElementType(MPElementType type); NSString *MPCalculateContent(MPElementType type, NSString *name, NSData *key, uint32_t counter); diff --git a/MasterPassword/MPTypes.m b/MasterPassword/MPTypes.m index 007ba0aa..263e7f51 100644 --- a/MasterPassword/MPTypes.m +++ b/MasterPassword/MPTypes.m @@ -46,8 +46,8 @@ NSString *NSStringFromMPElementType(MPElementType type) { return nil; switch (type) { - case MPElementTypeGeneratedSecure: - return @"Secure Password"; + case MPElementTypeGeneratedMaximum: + return @"Maximum Security Password"; case MPElementTypeGeneratedLong: return @"Long Password"; @@ -75,13 +75,48 @@ NSString *NSStringFromMPElementType(MPElementType type) { } } +NSString *NSStringShortFromMPElementType(MPElementType type) { + + if (!type) + return nil; + + switch (type) { + case MPElementTypeGeneratedMaximum: + return @"Maximum"; + + case MPElementTypeGeneratedLong: + return @"Long"; + + case MPElementTypeGeneratedMedium: + return @"Medium"; + + case MPElementTypeGeneratedShort: + return @"Short"; + + case MPElementTypeGeneratedBasic: + return @"Basic"; + + case MPElementTypeGeneratedPIN: + return @"PIN"; + + case MPElementTypeStoredPersonal: + return @"Personal"; + + case MPElementTypeStoredDevicePrivate: + return @"Device"; + + default: + Throw(@"Type not supported: %d", type); + } +} + Class ClassFromMPElementType(MPElementType type) { if (!type) return nil; switch (type) { - case MPElementTypeGeneratedSecure: + case MPElementTypeGeneratedMaximum: return [MPElementGeneratedEntity class]; case MPElementTypeGeneratedLong: @@ -141,7 +176,7 @@ NSString *MPCalculateContent(MPElementType type, NSString *name, NSData *key, ui withExtension:@"plist"]]; // Determine the seed whose bytes will be used for calculating a password - trc(@"seed from: hmac-sha256(key, 'com.lyndir.masterpassword' | %u | %@ | %u)", key, name.length, name, counter); + trc(@"seed from: hmac-sha256(%@, 'com.lyndir.masterpassword' | %u | %@ | %u)", key, name.length, name, counter); uint32_t ncounter = htonl(counter), nnameLength = htonl(name.length); NSData *seed = [[NSData dataByConcatenatingDatas: [@"com.lyndir.masterpassword" dataUsingEncoding:NSUTF8StringEncoding], diff --git a/MasterPassword/MPUserEntity.h b/MasterPassword/MPUserEntity.h index 45859195..54751768 100644 --- a/MasterPassword/MPUserEntity.h +++ b/MasterPassword/MPUserEntity.h @@ -2,7 +2,7 @@ // MPUserEntity.h // MasterPassword-iOS // -// Created by Maarten Billemont on 04/06/12. +// Created by Maarten Billemont on 11/06/12. // Copyright (c) 2012 Lyndir. All rights reserved. // @@ -13,12 +13,13 @@ @interface MPUserEntity : NSManagedObject -@property (nonatomic, retain) NSNumber *avatar_; -@property (nonatomic, retain) NSData *keyID; -@property (nonatomic, retain) NSDate *lastUsed; -@property (nonatomic, retain) NSString *name; -@property (nonatomic, retain) NSNumber *saveKey_; -@property (nonatomic, retain) NSSet *elements; +@property (nonatomic, retain) NSNumber * avatar_; +@property (nonatomic, retain) NSData * keyID; +@property (nonatomic, retain) NSDate * lastUsed; +@property (nonatomic, retain) NSString * name; +@property (nonatomic, retain) NSNumber * saveKey_; +@property (nonatomic, retain) NSNumber * defaultType_; +@property (nonatomic, retain) NSSet *elements; @end @interface MPUserEntity (CoreDataGeneratedAccessors) diff --git a/MasterPassword/MPUserEntity.m b/MasterPassword/MPUserEntity.m index 23032da5..559525b9 100644 --- a/MasterPassword/MPUserEntity.m +++ b/MasterPassword/MPUserEntity.m @@ -2,11 +2,12 @@ // MPUserEntity.m // MasterPassword-iOS // -// Created by Maarten Billemont on 04/06/12. +// Created by Maarten Billemont on 11/06/12. // Copyright (c) 2012 Lyndir. All rights reserved. // #import "MPUserEntity.h" +#import "MPElementEntity.h" @implementation MPUserEntity @@ -16,6 +17,7 @@ @dynamic lastUsed; @dynamic name; @dynamic saveKey_; +@dynamic defaultType_; @dynamic elements; @end diff --git a/MasterPassword/MasterPassword.xcdatamodeld/MasterPassword.xcdatamodel/contents b/MasterPassword/MasterPassword.xcdatamodeld/MasterPassword.xcdatamodel/contents index 8c463b83..e0ac495d 100644 --- a/MasterPassword/MasterPassword.xcdatamodeld/MasterPassword.xcdatamodel/contents +++ b/MasterPassword/MasterPassword.xcdatamodeld/MasterPassword.xcdatamodel/contents @@ -16,6 +16,7 @@ + @@ -26,6 +27,6 @@ - + \ No newline at end of file diff --git a/MasterPassword/iOS/MPMainViewController.m b/MasterPassword/iOS/MPMainViewController.m index 306739be..731cd77b 100644 --- a/MasterPassword/iOS/MPMainViewController.m +++ b/MasterPassword/iOS/MPMainViewController.m @@ -61,7 +61,7 @@ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - if ([[segue identifier] isEqualToString:@"MP_Main_ChooseType"]) + if ([[segue identifier] isEqualToString:@"MP_ChooseType"]) ((MPTypeViewController *)[segue destinationViewController]).delegate = self; } diff --git a/MasterPassword/iOS/MPPreferencesViewController.h b/MasterPassword/iOS/MPPreferencesViewController.h index b88ccd78..fe9ba675 100644 --- a/MasterPassword/iOS/MPPreferencesViewController.h +++ b/MasterPassword/iOS/MPPreferencesViewController.h @@ -8,14 +8,16 @@ #import #import "IASKAppSettingsViewController.h" +#import "MPTypeViewController.h" -@interface MPPreferencesViewController : UITableViewController +@interface MPPreferencesViewController : UITableViewController @property (weak, nonatomic) IBOutlet UIScrollView *avatarsView; @property (weak, nonatomic) IBOutlet UIButton *avatarTemplate; @property (weak, nonatomic) IBOutlet UISwitch *savePasswordSwitch; @property (weak, nonatomic) IBOutlet UITableViewCell *exportCell; @property (weak, nonatomic) IBOutlet UITableViewCell *changeMPCell; +@property (weak, nonatomic) IBOutlet UILabel *defaultTypeLabel; - (IBAction)didToggleSwitch:(UISwitch *)sender; - (IBAction)settings:(id)sender; diff --git a/MasterPassword/iOS/MPPreferencesViewController.m b/MasterPassword/iOS/MPPreferencesViewController.m index 235d5315..aebf7921 100644 --- a/MasterPassword/iOS/MPPreferencesViewController.m +++ b/MasterPassword/iOS/MPPreferencesViewController.m @@ -10,6 +10,7 @@ #import "MPPreferencesViewController.h" #import "MPAppDelegate.h" #import "MPAppDelegate_Key.h" +#import "MPAppDelegate_Store.h" @interface MPPreferencesViewController () @@ -21,6 +22,7 @@ @synthesize savePasswordSwitch; @synthesize exportCell; @synthesize changeMPCell; +@synthesize defaultTypeLabel; - (void)viewDidLoad { @@ -51,8 +53,10 @@ avatar.backgroundColor = [UIColor clearColor]; } options:0]; [avatar onSelect:^(BOOL selected) { - if (selected) + if (selected) { [MPAppDelegate get].activeUser.avatar = (unsigned)avatar.tag; + [[MPAppDelegate get] saveContext]; + } } options:0]; avatar.selected = (a == [MPAppDelegate get].activeUser.avatar); } @@ -70,6 +74,7 @@ } recurse:NO]; self.savePasswordSwitch.on = [MPAppDelegate get].activeUser.saveKey; + self.defaultTypeLabel.text = NSStringShortFromMPElementType([MPAppDelegate get].activeUser.defaultType); [super viewWillAppear:animated]; } @@ -87,9 +92,16 @@ [self setSavePasswordSwitch:nil]; [self setExportCell:nil]; [self setChangeMPCell:nil]; + [self setDefaultTypeLabel:nil]; [super viewDidUnload]; } +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + + if ([[segue identifier] isEqualToString:@"MP_ChooseType"]) + ((MPTypeViewController *)[segue destinationViewController]).delegate = self; +} + #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { @@ -113,6 +125,21 @@ [self.navigationController popViewControllerAnimated:YES]; } +#pragma mark - MPTypeDelegate + +- (void)didSelectType:(MPElementType)type { + + [MPAppDelegate get].activeUser.defaultType = type; + [[MPAppDelegate get] saveContext]; + + self.defaultTypeLabel.text = NSStringShortFromMPElementType([MPAppDelegate get].activeUser.defaultType); +} + +- (MPElementType)selectedType { + + return [MPAppDelegate get].activeUser.defaultType; +} + #pragma mark - IBActions - (IBAction)didToggleSwitch:(UISwitch *)sender { @@ -121,6 +148,7 @@ [[MPAppDelegate get] storeSavedKeyFor:[MPAppDelegate get].activeUser]; else [[MPAppDelegate get] forgetSavedKeyFor:[MPAppDelegate get].activeUser]; + [[MPAppDelegate get] saveContext]; } - (IBAction)settings:(UIBarButtonItem *)sender { diff --git a/MasterPassword/iOS/MPSearchDelegate.m b/MasterPassword/iOS/MPSearchDelegate.m index 734c64c8..d020b5ee 100644 --- a/MasterPassword/iOS/MPSearchDelegate.m +++ b/MasterPassword/iOS/MPSearchDelegate.m @@ -302,14 +302,14 @@ return; [self.fetchedResultsController.managedObjectContext performBlock:^{ - MPElementGeneratedEntity *element = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass( - [MPElementGeneratedEntity class]) + MPElementType type = [MPAppDelegate get].activeUser.defaultType; + MPElementEntity *element = [NSEntityDescription insertNewObjectForEntityForName:ClassNameFromMPElementType(type) inManagedObjectContext:self.fetchedResultsController.managedObjectContext]; - assert([element isKindOfClass:ClassFromMPElementType(element.type)]); - assert([MPAppDelegate get].activeUser.keyID); + assert([MPAppDelegate get].activeUser); element.name = siteName; element.user = [MPAppDelegate get].activeUser; + element.type = type; dispatch_async(dispatch_get_main_queue(), ^{ [self.delegate didSelectElement:element]; diff --git a/MasterPassword/iOS/MPTypeViewController.m b/MasterPassword/iOS/MPTypeViewController.m index 1f6f617b..6fe1fcfe 100644 --- a/MasterPassword/iOS/MPTypeViewController.m +++ b/MasterPassword/iOS/MPTypeViewController.m @@ -92,7 +92,7 @@ case 0: return NSNotFound; case 1: - return MPElementTypeGeneratedSecure; + return MPElementTypeGeneratedMaximum; case 2: return MPElementTypeGeneratedLong; case 3: diff --git a/MasterPassword/iOS/MPUnlockViewController.m b/MasterPassword/iOS/MPUnlockViewController.m index 102c71f0..01f29678 100644 --- a/MasterPassword/iOS/MPUnlockViewController.m +++ b/MasterPassword/iOS/MPUnlockViewController.m @@ -35,10 +35,6 @@ @synthesize avatarShadowColor = _avatarShadowColor; -// [UIView animateWithDuration:1.0f delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{ -// self.lock.alpha = 0.5f; -// } completion:nil]; - - (void)initAvatarAlert:(UIAlertView *)alert forUser:(MPUserEntity *)user { UIScrollView *alertAvatarScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(12, 30, 260, 150)]; @@ -50,9 +46,9 @@ for (int a = 0; a < MPAvatarCount; ++a) { UIButton *avatar = [self.avatarTemplate cloneAddedTo:alertAvatarScrollView]; - avatar.tag = a; - avatar.hidden = NO; - avatar.center = CGPointMake( + avatar.tag = a; + avatar.hidden = NO; + avatar.center = CGPointMake( (20 + self.avatarTemplate.bounds.size.width / 2) * (a + 1) + self.avatarTemplate.bounds.size.width / 2 * a, 20 + self.avatarTemplate.bounds.size.height / 2); [avatar setBackgroundImage:[UIImage imageNamed:PearlString(@"avatar-%d", a)] forState:UIControlStateNormal]; @@ -83,6 +79,32 @@ [alertAvatarScrollView setContentOffset:selectedOffset animated:YES]; } +- (void)initConfirmationAlert:(UIAlertView *)alert forUser:(MPUserEntity *)user { + + UIView *container = [[UIView alloc] initWithFrame:CGRectMake(12, 70, 260, 110)]; + [alert addSubview:container]; + + UIButton *alertAvatar = [self.avatarTemplate cloneAddedTo:container]; + alertAvatar.center = CGPointMake(130, 55); + alertAvatar.hidden = NO; + alertAvatar.layer.shadowColor = [UIColor blackColor].CGColor; + alertAvatar.layer.shadowOpacity = 1; + alertAvatar.layer.shadowRadius = 5; + alertAvatar.backgroundColor = [UIColor clearColor]; + [alertAvatar setBackgroundImage:[UIImage imageNamed:PearlString(@"avatar-%d", user.avatar)] forState:UIControlStateNormal]; + + UILabel *alertNameLabel = [self.nameLabel cloneAddedTo:container]; + alertNameLabel.center = alertAvatar.center; + alertNameLabel.text = user.name; + alertNameLabel.bounds = CGRectSetHeight(alertNameLabel.bounds, + [alertNameLabel.text sizeWithFont:self.nameLabel.font + constrainedToSize:CGSizeMake(alertNameLabel.bounds.size.width - 10, + 100) + lineBreakMode:self.nameLabel.lineBreakMode].height); + alertNameLabel.layer.cornerRadius = 5; + alertNameLabel.backgroundColor = [UIColor blackColor]; +} + - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); @@ -167,15 +189,15 @@ - (UIButton *)setupAvatar:(UIButton *)avatar forUser:(MPUserEntity *)user { - avatar.center = CGPointMake(avatar.center.x + [self.avatarToUser count] * 160, avatar.center.y); - avatar.hidden = NO; - avatar.layer.cornerRadius = avatar.bounds.size.height / 2; - avatar.layer.shadowColor = [UIColor blackColor].CGColor; - avatar.layer.shadowOpacity = 1; - avatar.layer.shadowRadius = 20; - avatar.layer.masksToBounds = NO; - avatar.backgroundColor = [UIColor clearColor]; - avatar.tag = user.avatar; + avatar.center = CGPointMake(avatar.center.x + [self.avatarToUser count] * 160, avatar.center.y); + avatar.hidden = NO; + avatar.layer.cornerRadius = avatar.bounds.size.height / 2; + avatar.layer.shadowColor = [UIColor blackColor].CGColor; + avatar.layer.shadowOpacity = 1; + avatar.layer.shadowRadius = 20; + avatar.layer.masksToBounds = NO; + avatar.backgroundColor = [UIColor clearColor]; + avatar.tag = user.avatar; [avatar setBackgroundImage:[UIImage imageNamed:PearlString(@"avatar-%u", user.avatar)] forState:UIControlStateNormal]; @@ -225,36 +247,78 @@ - (void)didSelectNewUserAvatar:(UIButton *)newUserAvatar { + MPUserEntity *newUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([MPUserEntity class]) + inManagedObjectContext:[MPAppDelegate managedObjectContext]]; + + [self showNewUserNameAlertFor:newUser completion:^(BOOL finished){ + newUserAvatar.selected = NO; + if (!finished) + [[MPAppDelegate managedObjectContext] deleteObject:newUser]; + }]; +} + +- (void)showNewUserNameAlertFor:(MPUserEntity *)newUser completion:(void (^)(BOOL finished))completion { + [PearlAlert showAlertWithTitle:@"Enter Your Name" message:nil viewStyle:UIAlertViewStylePlainTextInput initAlert:^(UIAlertView *alert, UITextField *firstField) { firstField.autocapitalizationType = UITextAutocapitalizationTypeWords; firstField.keyboardType = UIKeyboardTypeAlphabet; + firstField.text = newUser.name; + firstField.placeholder = @"eg. Robert Lee Mitchell"; } tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { - if (buttonIndex == [alert cancelButtonIndex]) + if (buttonIndex == [alert cancelButtonIndex]) { + completion(NO); return; + } - MPUserEntity *newUser = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([MPUserEntity class]) - inManagedObjectContext:[MPAppDelegate managedObjectContext]]; - newUser.name = [alert textFieldAtIndex:0].text; - - [PearlAlert showAlertWithTitle:@"Choose Your Avatar" - message:@"\n\n\n\n\n\n" viewStyle:UIAlertViewStyleDefault - initAlert:^(UIAlertView *_alert, UITextField *firstField) { - [self initAvatarAlert:_alert forUser:newUser]; - } - tappedButtonBlock:^(UIAlertView *_alert, NSInteger _buttonIndex) { - - newUserAvatar.selected = NO; - self.selectedUser = newUser; - - [self updateUsers]; - } cancelTitle:nil otherTitles:[PearlStrings get].commonButtonOkay, nil]; + // Save + newUser.name = [alert textFieldAtIndex:0].text; + [self showNewUserAvatarAlertFor:newUser completion:completion]; } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonSave, nil]; } +- (void)showNewUserAvatarAlertFor:(MPUserEntity *)newUser completion:(void (^)(BOOL finished))completion { + + [PearlAlert showAlertWithTitle:@"Choose Your Avatar" + message:@"\n\n\n\n\n\n" viewStyle:UIAlertViewStyleDefault + initAlert:^(UIAlertView *_alert, UITextField *_firstField) { + [self initAvatarAlert:_alert forUser:newUser]; + } + tappedButtonBlock:^(UIAlertView *_alert, NSInteger _buttonIndex) { + + // Okay + [self showNewUserConfirmationAlertFor:newUser completion:completion]; + } cancelTitle:nil otherTitles:[PearlStrings get].commonButtonOkay, nil]; +} + +- (void)showNewUserConfirmationAlertFor:(MPUserEntity *)newUser completion:(void (^)(BOOL finished))completion { + + [PearlAlert showAlertWithTitle:@"Is this correct?" + message: + @"Please double-check your name.\n" + @"\n\n\n\n\n\n" + viewStyle:UIAlertViewStyleDefault + initAlert:^void(UIAlertView *__alert, UITextField *__firstField) { + [self initConfirmationAlert:__alert forUser:newUser]; + } + tappedButtonBlock:^void(UIAlertView *__alert, NSInteger __buttonIndex) { + if (__buttonIndex == [__alert cancelButtonIndex]) { + [self showNewUserNameAlertFor:newUser completion:completion]; + return; + } + + // Confirm + completion(YES); + self.selectedUser = newUser; + + [self updateUsers]; + } + cancelTitle:@"Change" otherTitles:@"Confirm", nil]; +} + - (void)updateLayoutAnimated:(BOOL)animated allowScroll:(BOOL)allowScroll completion:(void (^)(BOOL finished))completion { if (animated) { @@ -276,7 +340,7 @@ if (self.selectedUser && !self.passwordView.alpha) { self.passwordView.alpha = 1; - self.avatarsView.center = CGPointMake(160, 100); + self.avatarsView.center = CGPointMake(160, 170); self.avatarsView.scrollEnabled = NO; self.nameLabel.center = CGPointMake(160, 84); self.nameLabel.backgroundColor = [UIColor blackColor]; @@ -286,7 +350,7 @@ } else if (!self.selectedUser && self.passwordView.alpha == 1) { self.passwordView.alpha = 0; - self.avatarsView.center = CGPointMake(160, 240); + self.avatarsView.center = CGPointMake(160, 310); self.avatarsView.scrollEnabled = YES; self.nameLabel.center = CGPointMake(160, 296); self.nameLabel.backgroundColor = [UIColor clearColor]; diff --git a/MasterPassword/iOS/MainStoryboard_iPhone.storyboard b/MasterPassword/iOS/MainStoryboard_iPhone.storyboard index 9db68ed5..852d8655 100644 --- a/MasterPassword/iOS/MainStoryboard_iPhone.storyboard +++ b/MasterPassword/iOS/MainStoryboard_iPhone.storyboard @@ -16,21 +16,21 @@ - + - - + + - + - - + @@ -67,7 +69,7 @@ The passwords aren't saved anywhere. This is a major advantage: if you lose you - - + @@ -109,7 +111,7 @@ The passwords aren't saved anywhere. This is a major advantage: if you lose you - - + @@ -142,7 +144,7 @@ The passwords aren't saved anywhere. This is a major advantage: if you lose you - - + @@ -175,7 +177,7 @@ The passwords aren't saved anywhere. This is a major advantage: if you lose you - - + @@ -221,7 +223,7 @@ The passwords aren't saved anywhere. This is a major advantage: if you lose you - + @@ -257,14 +259,14 @@ The passwords aren't saved anywhere. This is a major advantage: if you lose you - - + + - + - - + @@ -322,7 +327,7 @@ The passwords aren't saved anywhere. This is a major advantage: if you lose you - + @@ -501,7 +506,7 @@ The passwords aren't saved anywhere. This is a major advantage: if you lose you - + @@ -781,14 +786,6 @@ L4m3P4sSw0rD - @@ -842,7 +839,7 @@ L4m3P4sSw0rD - +