2
0

Facebook updates + Mac fixes.

[UPDATED]   Facebook integration bumped for iOS 6.
[FIXED]     Bringing Mac version back up to date.  Compiles again and
            runs with UI bugs.
[ADDED]     Mac: User selection.
This commit is contained in:
Maarten Billemont
2012-10-30 22:54:34 -04:00
parent 678545cc26
commit 05ab38b998
26 changed files with 1463 additions and 1307 deletions

View File

@@ -26,7 +26,7 @@ id<MPAlgorithm> MPAlgorithmForVersion(NSUInteger version) {
id<MPAlgorithm> algorithm = [versionToAlgorithm objectForKey:@(version)];
if (!algorithm)
if ((algorithm = [NSClassFromString(PearlString(@"MPAlgorithmV%u", version)) new]))
if ((algorithm = [NSClassFromString(PearlString(@"MPAlgorithmV%lu", (unsigned long)version)) new]))
[versionToAlgorithm setObject:algorithm forKey:@(version)];
return algorithm;

View File

@@ -6,10 +6,8 @@
// Copyright (c) 2011 Lyndir. All rights reserved.
//
#import <Crashlytics/Crashlytics.h>
#import "MPAppDelegate_Key.h"
#import "MPAppDelegate_Store.h"
#import "LocalyticsSession.h"
@implementation MPAppDelegate_Shared (Key)
@@ -101,7 +99,9 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
// Migrate existing elements.
MPKey *recoverKey = nil;
#ifdef PEARL_UIKIT
PearlAlert *activityAlert = [PearlAlert showActivityWithTitle:PearlString(@"Migrating %d sites...", [user.elements count])];
#endif
for (MPElementEntity *element in user.elements) {
if (element.type & MPElementTypeClassStored && ![element contentUsingKey:tryKey]) {
@@ -111,6 +111,8 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
while (!content) {
__block NSString *masterPassword = nil;
#ifdef PEARL_UIKIT
dispatch_group_t recoverPasswordGroup = dispatch_group_create();
dispatch_group_enter(recoverPasswordGroup);
[PearlAlert showAlertWithTitle:@"Enter Old Master Password"
@@ -130,6 +132,7 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
}
} cancelTitle:@"Don't Migrate" otherTitles:@"Migrate", nil];
dispatch_group_wait(recoverPasswordGroup, DISPATCH_TIME_FOREVER);
#endif
if (!masterPassword)
// Don't Migrate
@@ -149,7 +152,9 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
}
}
[[MPAppDelegate_Shared get] saveContext];
#ifdef PEARL_UIKIT
[activityAlert dismissAlert];
#endif
}
}
@@ -190,7 +195,9 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:MPCheckpointSignInFailed];
#endif
#ifdef LOCALYTICS
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointSignInFailed attributes:nil];
#endif
}
return NO;
@@ -203,12 +210,14 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
}
@try {
if ([[MPiOSConfig get].sendInfo boolValue]) {
if ([[MPConfig get].sendInfo boolValue]) {
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight addCustomEnvironmentInformation:user.userID forKey:@"username"];
#endif
#ifdef CRASHLYTICS
[Crashlytics setObjectValue:user.userID forKey:@"username"];
[Crashlytics setUserName:user.userID];
#endif
}
}
@catch (id exception) {
@@ -227,7 +236,9 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:MPCheckpointSignedIn];
#endif
#ifdef LOCALYTICS
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointSignedIn attributes:nil];
#endif
return YES;
}

View File

@@ -7,7 +7,6 @@
//
#import "MPAppDelegate_Store.h"
#import "LocalyticsSession.h"
@implementation MPAppDelegate_Shared (Store)
@@ -136,9 +135,11 @@
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:iCloudEnabled? MPCheckpointCloudEnabled: MPCheckpointCloudDisabled];
#endif
#ifdef LOCALYTICS
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointCloud attributes:@{
@"enabled": iCloudEnabled? @"YES": @"NO"
}];
#endif
[MPConfig get].iCloud = @(iCloudEnabled);
}
@@ -151,11 +152,13 @@
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:PearlString(MPCheckpointMPErrorUbiquity @"_%d", cause)];
#endif
#ifdef LOCALYTICS
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointMPErrorUbiquity attributes:@{
@"cause": @(cause),
@"error.domain": error.domain,
@"error.code": @(error.code)
}];
#endif
switch (cause) {
case UbiquityStoreManagerErrorCauseDeleteStore:
@@ -172,7 +175,9 @@
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:MPCheckpointLocalStoreReset];
#endif
#ifdef LOCALYTICS
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointLocalStoreReset attributes:nil];
#endif
manager.hardResetEnabled = YES;
[manager hardResetLocalStorage];
@@ -190,7 +195,9 @@
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:MPCheckpointCloudStoreReset];
#endif
#ifdef LOCALYTICS
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointCloudStoreReset attributes:nil];
#endif
manager.hardResetEnabled = YES;
[manager hardResetCloudStorage];
break;
@@ -276,7 +283,7 @@
return MPImportResultInternalError;
}
if ([users count] > 1) {
err(@"While looking for user: %@, found more than one: %u", importUserName, [users count]);
err(@"While looking for user: %@, found more than one: %lu", importUserName, (unsigned long)[users count]);
return MPImportResultInternalError;
}
@@ -337,7 +344,7 @@
}
// Ask for confirmation to import these sites and the master password of the user.
inf(@"Importing %u sites, deleting %u sites, for user: %@", [importedSiteElements count], [elementsToDelete count], [MPUserEntity idFor:importUserName]);
inf(@"Importing %lu sites, deleting %lu sites, for user: %@", (unsigned long)[importedSiteElements count], (unsigned long)[elementsToDelete count], [MPUserEntity idFor:importUserName]);
NSString *userMasterPassword = userPassword(user.name, [importedSiteElements count], [elementsToDelete count]);
if (!userMasterPassword) {
inf(@"Import cancelled.");
@@ -424,7 +431,9 @@
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:MPCheckpointSitesImported];
#endif
#ifdef LOCALYTICS
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointSitesImported attributes:nil];
#endif
return MPImportResultSuccess;
}
@@ -480,16 +489,18 @@
content = element.exportContent;
}
[export appendFormat:@"%@ %8d %8s %20s\t%@\n",
[[NSDateFormatter rfc3339DateFormatter] stringFromDate:lastUsed], uses,
[PearlString(@"%u:%u", type, version) UTF8String], [name UTF8String], content
[export appendFormat:@"%@ %8ld %8s %20s\t%@\n",
[[NSDateFormatter rfc3339DateFormatter] stringFromDate:lastUsed], (long)uses,
[PearlString(@"%u:%lu", type, (unsigned long)version) UTF8String], [name UTF8String], content
? content: @""];
}
#ifdef TESTFLIGHT_SDK_VERSION
[TestFlight passCheckpoint:MPCheckpointSitesExported];
#endif
#ifdef LOCALYTICS
[[LocalyticsSession sharedLocalyticsSession] tagEvent:MPCheckpointSitesExported attributes:nil];
#endif
return export;
}

View File

@@ -10,6 +10,7 @@
@interface MPConfig : PearlConfig
@property (nonatomic, retain) NSNumber *sendInfo;
@property (nonatomic, retain) NSNumber *rememberLogin;
@property (nonatomic, retain) NSNumber *iCloud;

View File

@@ -6,10 +6,11 @@
// Copyright (c) 2012 Lyndir. All rights reserved.
//
#import "MPConfig.h"
#import "MPAppDelegate.h"
@implementation MPConfig
@dynamic rememberLogin, iCloud, iCloudDecided;
@dynamic sendInfo, rememberLogin, iCloud, iCloudDecided;
- (id)init {
@@ -18,6 +19,7 @@
[self.defaults registerDefaults:@{NSStringFromSelector(@selector(askForReviews)): @YES,
NSStringFromSelector(@selector(sendInfo)): @NO,
NSStringFromSelector(@selector(rememberLogin)): @NO,
NSStringFromSelector(@selector(iCloud)): @NO,
NSStringFromSelector(@selector(iCloudDecided)): @NO}];

View File

@@ -132,8 +132,8 @@
- (NSString *)debugDescription {
return PearlString(@"{%@: name=%@, user=%@, type=%d, uses=%d, lastUsed=%@, version=%d, loginName=%@, requiresExplicitMigration=%d}",
NSStringFromClass([self class]), self.name, self.user.name, self.type, self.uses, self.lastUsed, self.version,
return PearlString(@"{%@: name=%@, user=%@, type=%d, uses=%ld, lastUsed=%@, version=%ld, loginName=%@, requiresExplicitMigration=%d}",
NSStringFromClass([self class]), self.name, self.user.name, self.type, (long)self.uses, self.lastUsed, (long)self.version,
self.loginName, self.requiresExplicitMigration);
}
@@ -141,9 +141,9 @@
while (self.version < MPAlgorithmDefaultVersion)
if ([MPAlgorithmForVersion(self.version + 1) migrateElement:self explicit:explicit])
inf(@"%@ migration to version: %d succeeded for element: %@", explicit? @"Explicit": @"Automatic", self.version + 1, self);
inf(@"%@ migration to version: %ld succeeded for element: %@", explicit? @"Explicit": @"Automatic", (long)self.version + 1, self);
else {
wrn(@"%@ migration to version: %d failed for element: %@", explicit? @"Explicit": @"Automatic", self.version + 1, self);
wrn(@"%@ migration to version: %ld failed for element: %@", explicit? @"Explicit": @"Automatic", (long)self.version + 1, self);
return NO;
}

View File

@@ -68,7 +68,7 @@ typedef enum {
#define MPCheckpointAppGorillas @"MPCheckpointAppGorillas"
#define MPCheckpointAppDeBlock @"MPCheckpointAppDeBlock"
#define MPNotificationSignedIn @"MPNotificationKeySet"
#define MPNotificationSignedOut @"MPNotificationKeyUnset"
#define MPNotificationSignedIn @"MPNotificationSignedIn"
#define MPNotificationSignedOut @"MPNotificationSignedOut"
#define MPNotificationKeyForgotten @"MPNotificationKeyForgotten"
#define MPNotificationElementUpdated @"MPNotificationElementUpdated"

View File

@@ -12,18 +12,22 @@
@interface MPAppDelegate : MPAppDelegate_Shared<NSApplicationDelegate>
@property (strong) NSStatusItem *statusItem;
@property (strong) MPPasswordWindowController *passwordWindow;
@property (weak) IBOutlet NSMenuItem *lockItem;
@property (weak) IBOutlet NSMenuItem *showItem;
@property (strong) IBOutlet NSMenu *statusMenu;
@property (weak) IBOutlet NSMenuItem *useICloudItem;
@property (weak) IBOutlet NSMenuItem *rememberPasswordItem;
@property (weak) IBOutlet NSMenuItem *savePasswordItem;
@property (nonatomic, strong) NSStatusItem *statusItem;
@property (nonatomic, strong) MPPasswordWindowController *passwordWindow;
@property (nonatomic, weak) IBOutlet NSMenuItem *lockItem;
@property (nonatomic, weak) IBOutlet NSMenuItem *showItem;
@property (nonatomic, strong) IBOutlet NSMenu *statusMenu;
@property (nonatomic, weak) IBOutlet NSMenuItem *useICloudItem;
@property (nonatomic, weak) IBOutlet NSMenuItem *rememberPasswordItem;
@property (nonatomic, weak) IBOutlet NSMenuItem *savePasswordItem;
@property (nonatomic, weak) IBOutlet NSMenuItem *createUserItem;
@property (nonatomic, weak) IBOutlet NSMenuItem *usersItem;
+ (MPAppDelegate *)get;
- (IBAction)activate:(id)sender;
- (IBAction)togglePreference:(NSMenuItem *)sender;
- (IBAction)newUser:(NSMenuItem *)sender;
- (IBAction)signOut:(id)sender;
@end

View File

@@ -25,7 +25,6 @@
@synthesize passwordWindow;
@synthesize key;
@synthesize keyID;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfour-char-constants"
@@ -37,7 +36,7 @@ static EventHotKeyID MPShowHotKey = {.signature = 'show', .id = 1};
[MPConfig get];
#ifdef DEBUG
[PearlLogger get].autoprintLevel = PearlLogLevelTrace;
[PearlLogger get].printLevel = PearlLogLevelTrace;
#endif
}
@@ -62,10 +61,56 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
return eventNotHandledErr;
}
- (void)updateUsers {
[[[self.usersItem submenu] itemArray] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (idx > 1)
[[self.usersItem submenu] removeItemAtIndex:(NSInteger)idx];
}];
NSManagedObjectContext *moc = [MPAppDelegate managedObjectContextIfReady];
if (!moc) {
[self.createUserItem setEnabled:NO];
[[self.usersItem.submenu addItemWithTitle:@"Loading..." action:NULL keyEquivalent:@""] setEnabled:NO];
return;
}
[self.createUserItem setEnabled:YES];
[moc performBlockAndWait:^{
NSArray *users = nil;
NSError *error = nil;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPUserEntity class])];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"lastUsed" ascending:NO]];
users = [moc executeFetchRequest:fetchRequest error:&error];
if (!users)
err(@"Failed to load users: %@", error);
for (MPUserEntity *user in users) {
NSMenuItem *userItem = [[NSMenuItem alloc] initWithTitle:user.name action:@selector(selectUser:) keyEquivalent:@""];
[userItem setTarget:self];
[userItem setRepresentedObject:user];
[[self.usersItem submenu] addItem:userItem];
}
}];
}
- (void)selectUser:(NSMenuItem *)item {
NSAssert1([[item representedObject] isKindOfClass:[MPUserEntity class]], @"Not a user: %@", item.representedObject);
self.activeUser = item.representedObject;
[[[self.usersItem submenu] itemArray] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[obj setState:NSOffState];
}];
item.state = NSOnState;
}
- (void)showMenu {
self.rememberPasswordItem.state = [[MPConfig get].rememberKey boolValue]? NSOnState: NSOffState;
self.savePasswordItem.state = [[MPConfig get].saveKey boolValue]? NSOnState: NSOffState;
self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState;
self.savePasswordItem.state = [MPAppDelegate get].activeUser.saveKey? NSOnState: NSOffState;
self.showItem.enabled = ![self.passwordWindow.window isVisible];
[self.statusItem popUpStatusItemMenu:self.statusMenu];
@@ -84,17 +129,25 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
if (sender == useICloudItem)
[self.storeManager useiCloudStore:sender.state == NSOffState alertUser:YES];
if (sender == rememberPasswordItem)
[MPConfig get].rememberKey = [NSNumber numberWithBool:![[MPConfig get].rememberKey boolValue]];
[MPConfig get].rememberLogin = [NSNumber numberWithBool:![[MPConfig get].rememberLogin boolValue]];
if (sender == savePasswordItem)
[MPConfig get].saveKey = [NSNumber numberWithBool:![[MPConfig get].saveKey boolValue]];
[MPAppDelegate get].activeUser.saveKey = ![MPAppDelegate get].activeUser.saveKey;
}
- (IBAction)newUser:(NSMenuItem *)sender {
}
- (IBAction)signOut:(id)sender {
[self signOutAnimated:YES];
}
- (void)didUpdateConfigForKey:(SEL)configKey fromValue:(id)oldValue {
if (configKey == @selector(rememberKey))
self.rememberPasswordItem.state = [[MPConfig get].rememberKey boolValue]? NSOnState: NSOffState;
if (configKey == @selector(rememberLogin))
self.rememberPasswordItem.state = [[MPConfig get].rememberLogin boolValue]? NSOnState: NSOffState;
if (configKey == @selector(saveKey))
self.savePasswordItem.state = [[MPConfig get].saveKey boolValue]? NSOnState: NSOffState;
self.savePasswordItem.state = [MPAppDelegate get].activeUser.saveKey? NSOnState: NSOffState;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
@@ -111,7 +164,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window {
return [[self managedObjectContext] undoManager];
return [[self managedObjectContextIfReady] undoManager];
}
#pragma mark - NSApplicationDelegate
@@ -132,6 +185,16 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
self.statusItem.highlightMode = YES;
self.statusItem.target = self;
self.statusItem.action = @selector(showMenu);
[[NSNotificationCenter defaultCenter] addObserverForName:PersistentStoreDidChange object:nil queue:nil usingBlock:
^(NSNotification *note) {
[self updateUsers];
}];
[[NSNotificationCenter defaultCenter] addObserverForName:PersistentStoreDidMergeChanges object:nil queue:nil usingBlock:
^(NSNotification *note) {
[self updateUsers];
}];
[self updateUsers];
// Global hotkey.
EventHotKeyRef hotKeyRef;
@@ -163,28 +226,28 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (void)applicationWillResignActive:(NSNotification *)notification {
if (![[MPConfig get].rememberKey boolValue])
if (![[MPConfig get].rememberLogin boolValue])
self.key = nil;
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
// Save changes in the application's managed object context before the application terminates.
if (![self managedObjectContext]) {
if (![self managedObjectContextIfReady]) {
return NSTerminateNow;
}
if (![[self managedObjectContext] commitEditing]) {
if (![[self managedObjectContextIfReady] commitEditing]) {
NSLog(@"%@:%@ unable to commit editing to terminate", [self class], NSStringFromSelector(_cmd));
return NSTerminateCancel;
}
if (![[self managedObjectContext] hasChanges]) {
if (![[self managedObjectContextIfReady] hasChanges]) {
return NSTerminateNow;
}
NSError *error = nil;
if (![[self managedObjectContext] save:&error]) {
if (![[self managedObjectContextIfReady] save:&error]) {
// Customize this code block to include application-specific recovery steps.
BOOL result = [sender presentError:error];
@@ -215,9 +278,48 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
#pragma mark - UbiquityStoreManagerDelegate
- (void)ubiquityStoreManager:(UbiquityStoreManager *)manager didSwitchToiCloud:(BOOL)iCloudEnabled {
[super ubiquityStoreManager:manager didSwitchToiCloud:iCloudEnabled];
self.useICloudItem.state = iCloudEnabled? NSOnState: NSOffState;
self.useICloudItem.enabled = !iCloudEnabled;
if (![[MPConfig get].iCloudDecided boolValue]) {
if (iCloudEnabled)
return;
switch ([[NSAlert alertWithMessageText:@"iCloud Is Disabled"
defaultButton:@"Enable iCloud" alternateButton:@"Leave iCloud Off" otherButton:@"Explain?"
informativeTextWithFormat:@"It is highly recommended you enable iCloud."] runModal]) {
case NSAlertDefaultReturn: {
[MPConfig get].iCloudDecided = @YES;
[manager useiCloudStore:YES alertUser:NO];
break;
}
case NSAlertOtherReturn: {
[[NSAlert alertWithMessageText:@"About iCloud"
defaultButton:[PearlStrings get].commonButtonThanks alternateButton:nil otherButton:nil
informativeTextWithFormat:
@"iCloud is Apple's solution for saving your data in \"the cloud\" "
@"and making sure your other iPhones, iPads and Macs are in sync.\n\n"
@"For Master Password, that means your sites are available on all your "
@"Apple devices, and you always have a backup of them in case "
@"you loose one or need to restore.\n\n"
@"Because of the way Master Password works, it doesn't need to send your "
@"site's passwords to Apple. Only their names are saved to make it easier "
@"for you to find the site you need. For some sites you may have set "
@"a user-specified password: these are sent to iCloud after being encrypted "
@"with your master password.\n\n"
@"Apple can never see any of your passwords."] runModal];
[self ubiquityStoreManager:manager didSwitchToiCloud:iCloudEnabled];
break;
}
default:
break;
};
}
}
@end

View File

@@ -0,0 +1,15 @@
//
// MPConfig.h
// MasterPassword
//
// Created by Maarten Billemont on 02/01/12.
// Copyright (c) 2012 Lyndir. All rights reserved.
//
#import "MPConfig.h"
@interface MPMacConfig : MPConfig
+ (MPMacConfig *)get;
@end

View File

@@ -0,0 +1,26 @@
//
// MPConfig.m
// MasterPassword
//
// Created by Maarten Billemont on 02/01/12.
// Copyright (c) 2012 Lyndir. All rights reserved.
//
@implementation MPMacConfig
- (id)init {
if (!(self = [super init]))
return self;
[self.defaults registerDefaults:@{NSStringFromSelector(@selector(iTunesID)): @"510296984"}];
return self;
}
+ (MPMacConfig *)get {
return (MPMacConfig *)[super get];
}
@end

View File

@@ -13,11 +13,13 @@
NSString *_content;
}
@property (strong) NSString *content;
@property (nonatomic, strong) NSString *content;
@property (weak) IBOutlet NSTextField *siteField;
@property (weak) IBOutlet NSTextField *contentField;
@property (weak) IBOutlet NSTextField *tipField;
@property (nonatomic, weak) IBOutlet NSTextField *siteField;
@property (nonatomic, weak) IBOutlet NSTextField *contentField;
@property (nonatomic, weak) IBOutlet NSTextField *tipField;
@property (nonatomic, weak) IBOutlet NSView *contentContainer;
@property (nonatomic, weak) IBOutlet NSProgressIndicator *progressView;
- (void)unlock;

View File

@@ -58,9 +58,9 @@
- (void)unlock {
if (![MPAppDelegate get].key)
// Try and load the key from the keychain.
[[MPAppDelegate get] loadStoredKey];
if ([[MPAppDelegate get] signInAsUser:[MPAppDelegate get].activeUser usingMasterPassword:nil])
// Load the key from the keychain.
return;
if (![MPAppDelegate get].key)
// Ask the user to set the key through his master password.
@@ -69,8 +69,8 @@
return;
NSAlert *alert = [NSAlert alertWithMessageText:@"Master Password is locked."
defaultButton:@"Unlock" alternateButton:@"Change" otherButton:@"Quit"
informativeTextWithFormat:@"Your master password is required to unlock the application."];
defaultButton:@"Unlock" alternateButton:@"Change" otherButton:@"Cancel"
informativeTextWithFormat:@"The master password is required to unlock the application for:\n\n%@", [MPAppDelegate get].activeUser.name];
NSSecureTextField *passwordField = [[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 22)];
[alert setAccessoryView:passwordField];
[alert layout];
@@ -94,17 +94,31 @@
@"You can always change back to your current master password later.\n"
@"Your current sites and passwords will then become available again."] runModal]
== 1)
[[MPAppDelegate get] forgetKey];
[[MPAppDelegate get] forgetSavedKeyFor:[MPAppDelegate get].activeUser];
break;
case NSAlertOtherReturn:
// "Quit" button.
[[NSApplication sharedApplication] terminate:self];
// "Cancel" button.
[self.window close];
return;
case NSAlertDefaultReturn:
case NSAlertDefaultReturn: {
// "Unlock" button.
[[MPAppDelegate get] tryMasterPassword:[(NSSecureTextField *)alert.accessoryView stringValue]];
self.contentContainer.alphaValue = 0;
[self.progressView startAnimation:nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
BOOL success = [[MPAppDelegate get] signInAsUser:[MPAppDelegate get].activeUser usingMasterPassword:[(NSSecureTextField *)alert.accessoryView stringValue]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.progressView stopAnimation:nil];
if (success)
self.contentContainer.alphaValue = 1;
else
[self.window close];
});
});
}
}
}
@@ -112,7 +126,7 @@
forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(NSInteger *)index {
NSString *query = [[control stringValue] substringWithRange:charRange];
if (![query length] || ![MPAppDelegate get].keyID)
if (![query length] || ![MPAppDelegate get].key)
return nil;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass([MPElementEntity class])];
@@ -121,7 +135,7 @@
query, query, [MPAppDelegate get].activeUser];
NSError *error = nil;
self.siteResults = [[MPAppDelegate managedObjectContext] executeFetchRequest:fetchRequest error:&error];
self.siteResults = [[MPAppDelegate managedObjectContextIfReady] executeFetchRequest:fetchRequest error:&error];
if (error)
err(@"Couldn't fetch elements: %@", error);

File diff suppressed because it is too large Load Diff

View File

@@ -29,7 +29,7 @@
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2012 Lyndir. All rights reserved.</string>
<string>Copyright © 2011-2013 Lyndir. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>

View File

@@ -2,12 +2,16 @@
// Prefix header for all source files of the 'MasterPassword' target in the 'MasterPassword' project
//
#import "Pearl-Prefix.pch"
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif
#import "Pearl-Prefix.pch"
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "MPTypes.h"
#import "MPMacConfig.h"
#endif

View File

@@ -2,18 +2,18 @@
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1070</int>
<string key="IBDocument.SystemVersion">11D50</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<string key="IBDocument.SystemVersion">12C60</string>
<string key="IBDocument.InterfaceBuilderVersion">2840</string>
<string key="IBDocument.AppKitVersion">1187.34</string>
<string key="IBDocument.HIToolboxVersion">625.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="NS.object.0">2182</string>
<string key="NS.object.0">2840</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>NSMenuItem</string>
<string>NSMenu</string>
<string>NSCustomObject</string>
<string>NSMenu</string>
<string>NSMenuItem</string>
<string>NSUserDefaultsController</string>
</array>
<array key="IBDocument.PluginDependencies">
@@ -61,6 +61,38 @@
<string key="NSResourceName">NSMenuMixedState</string>
</object>
</object>
<object class="NSMenuItem" id="11982480">
<reference key="NSMenu" ref="764588027"/>
<string key="NSTitle">Users</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="552246001"/>
<reference key="NSMixedImage" ref="752047669"/>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="934187555">
<string key="NSTitle">Users</string>
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="576787569">
<reference key="NSMenu" ref="934187555"/>
<string key="NSTitle">New User</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="552246001"/>
<reference key="NSMixedImage" ref="752047669"/>
</object>
<object class="NSMenuItem" id="925131766">
<reference key="NSMenu" ref="934187555"/>
<bool key="NSIsDisabled">YES</bool>
<bool key="NSIsSeparator">YES</bool>
<string key="NSTitle"/>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="552246001"/>
<reference key="NSMixedImage" ref="752047669"/>
</object>
</array>
</object>
</object>
<object class="NSMenuItem" id="851296005">
<reference key="NSMenu" ref="764588027"/>
<string key="NSTitle">Preferences</string>
@@ -286,6 +318,30 @@
</object>
<int key="connectionID">754</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">newUser:</string>
<reference key="source" ref="976324537"/>
<reference key="destination" ref="576787569"/>
</object>
<int key="connectionID">761</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">usersItem</string>
<reference key="source" ref="976324537"/>
<reference key="destination" ref="11982480"/>
</object>
<int key="connectionID">762</int>
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">createUserItem</string>
<reference key="source" ref="976324537"/>
<reference key="destination" ref="576787569"/>
</object>
<int key="connectionID">763</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
@@ -338,6 +394,7 @@
<reference ref="846612332"/>
<reference ref="229948989"/>
<reference ref="851296005"/>
<reference ref="11982480"/>
</array>
<reference key="parent" ref="0"/>
</object>
@@ -412,6 +469,33 @@
<reference key="object" ref="123831322"/>
<reference key="parent" ref="800575174"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">755</int>
<reference key="object" ref="11982480"/>
<array class="NSMutableArray" key="children">
<reference ref="934187555"/>
</array>
<reference key="parent" ref="764588027"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">756</int>
<reference key="object" ref="934187555"/>
<array class="NSMutableArray" key="children">
<reference ref="576787569"/>
<reference ref="925131766"/>
</array>
<reference key="parent" ref="11982480"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">757</int>
<reference key="object" ref="576787569"/>
<reference key="parent" ref="934187555"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">759</int>
<reference key="object" ref="925131766"/>
<reference key="parent" ref="934187555"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
@@ -434,21 +518,25 @@
<string key="746.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="747.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="748.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="755.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="756.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="757.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<string key="759.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">754</int>
<int key="maxID">763</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">MPAppDelegate</string>
<string key="superclassName">NSObject</string>
<string key="superclassName">MPAppDelegate_Shared</string>
<dictionary class="NSMutableDictionary" key="actions">
<string key="activate:">id</string>
<string key="signOut:">id</string>
<string key="newUser:">NSMenuItem</string>
<string key="togglePreference:">NSMenuItem</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="actionInfosByName">
@@ -456,9 +544,9 @@
<string key="name">activate:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo" key="signOut:">
<string key="name">signOut:</string>
<string key="candidateClassName">id</string>
<object class="IBActionInfo" key="newUser:">
<string key="name">newUser:</string>
<string key="candidateClassName">NSMenuItem</string>
</object>
<object class="IBActionInfo" key="togglePreference:">
<string key="name">togglePreference:</string>
@@ -467,17 +555,23 @@
</dictionary>
<dictionary class="NSMutableDictionary" key="outlets">
<string key="lockItem">NSMenuItem</string>
<string key="newUserItem">NSMenuItem</string>
<string key="rememberPasswordItem">NSMenuItem</string>
<string key="savePasswordItem">NSMenuItem</string>
<string key="showItem">NSMenuItem</string>
<string key="statusMenu">NSMenu</string>
<string key="useICloudItem">NSMenuItem</string>
<string key="usersItem">NSMenuItem</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
<object class="IBToOneOutletInfo" key="lockItem">
<string key="name">lockItem</string>
<string key="candidateClassName">NSMenuItem</string>
</object>
<object class="IBToOneOutletInfo" key="newUserItem">
<string key="name">newUserItem</string>
<string key="candidateClassName">NSMenuItem</string>
</object>
<object class="IBToOneOutletInfo" key="rememberPasswordItem">
<string key="name">rememberPasswordItem</string>
<string key="candidateClassName">NSMenuItem</string>
@@ -498,12 +592,24 @@
<string key="name">useICloudItem</string>
<string key="candidateClassName">NSMenuItem</string>
</object>
<object class="IBToOneOutletInfo" key="usersItem">
<string key="name">usersItem</string>
<string key="candidateClassName">NSMenuItem</string>
</object>
</dictionary>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MPAppDelegate.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">MPAppDelegate_Shared</string>
<string key="superclassName">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MPAppDelegate_Shared.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>

View File

@@ -383,9 +383,7 @@
inf(@"Re-activated");
[[MPAppDelegate get] checkConfig];
if (FBSession.activeSession.state == FBSessionStateCreatedOpening)
// An old Facebook Login session that wasn't finished. Clean it up.
[FBSession.activeSession close];
[FBSession.activeSession handleDidBecomeActive];
[[LocalyticsSession sharedLocalyticsSession] resume];
[[LocalyticsSession sharedLocalyticsSession] upload];

View File

@@ -935,8 +935,10 @@
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
return [FBSession openActiveSessionWithPermissions:nil allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
return [FBSession openActiveSessionWithPublishPermissions:nil
defaultAudience:FBSessionDefaultAudienceEveryone
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}

View File

@@ -10,7 +10,6 @@
@interface MPiOSConfig : MPConfig
@property (nonatomic, retain) NSNumber *sendInfo;
@property (nonatomic, retain) NSNumber *helpHidden;
@property (nonatomic, retain) NSNumber *siteInfoHidden;
@property (nonatomic, retain) NSNumber *showQuickStart;

View File

@@ -14,8 +14,7 @@
if (!(self = [super init]))
return self;
[self.defaults registerDefaults:@{NSStringFromSelector(@selector(sendInfo)): @NO,
NSStringFromSelector(@selector(helpHidden)): @NO,
[self.defaults registerDefaults:@{ NSStringFromSelector(@selector(helpHidden)): @NO,
NSStringFromSelector(@selector(siteInfoHidden)): @YES,
NSStringFromSelector(@selector(showQuickStart)): @YES,
NSStringFromSelector(@selector(iTunesID)): @"510296984",

View File

@@ -93,7 +93,7 @@
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>© 2011-2012, Lyndir</string>
<string>Copyright © 2011-2013 Lyndir. All rights reserved.</string>
<key>ReplacementFonts</key>
<dict>
<key>Futura-CondensedExtraBold</key>

View File

@@ -18,6 +18,9 @@
#import "TestFlight.h"
#import <Crashlytics/Crashlytics.h>
#import "LocalyticsSession.h"
#define LOCALYTICS 1
#define CRASHLYTICS 1
#import "MPTypes.h"
#import "MPiOSConfig.h"