2
0

Compare commits

...

14 Commits

Author SHA1 Message Date
Maarten Billemont
363d6f6639 Test configuration was removed for Release. 2020-05-18 13:01:16 -04:00
Maarten Billemont
eb1632cb62 Install cocoapods dependencies & gradle works on JDK 11 now. 2020-05-18 12:43:37 -04:00
Maarten Billemont
73fadaef7f iOS uses Xcode 11 now. 2020-05-18 12:15:36 -04:00
Maarten Billemont
60200f6302 Fix all versions advertising themselves as V0. 2020-05-18 12:14:44 -04:00
Maarten Billemont
cce8db5c48 Purge unused and deprecated UISearchDisplayController. 2020-05-18 11:10:23 -04:00
Maarten Billemont
6f3da5ccf0 Harmonize consent features. 2020-05-16 22:34:49 -04:00
Maarten Billemont
52c87eaeca Keep sites sorted by name on export to ensure consistency. 2020-05-16 16:03:42 -04:00
Maarten Billemont
1dccdd0a3c Improvements to algorithm and counter steppers. 2020-05-16 15:40:59 -04:00
Maarten Billemont
eb8d10ed05 Use new UN notification API. 2020-05-14 10:32:04 -04:00
Maarten Billemont
d9e5f77bee Resolve export state generation. 2020-05-14 00:04:29 -04:00
Maarten Billemont
60f60d087e Embed views using embed segue instead of MPRootSegue. 2020-05-12 23:27:56 -04:00
Maarten Billemont
df97dec2fe Sentry user login & MPError arguments. 2020-05-12 10:54:15 -04:00
Maarten Billemont
3bac8d9e0a iPad fixes & log initial start-up crashes. 2020-05-11 21:28:27 -04:00
Maarten Billemont
3fa7e1e8a1 Ensure Countly does not use the IDFA. 2020-05-02 12:31:54 -04:00
30 changed files with 241 additions and 223 deletions

View File

@@ -9,10 +9,12 @@ build_project:
- "( ./lib/bin/build_libsodium-macos clean && ./lib/bin/build_libsodium-macos )"
- "( ./lib/bin/build_libjson-c-macos clean && ./lib/bin/build_libjson-c-macos )"
- "( cd ./platform-independent/c/cli && ./clean && targets=all ./build && ./mpw-tests && ./mpw-cli-tests )"
- "( export JAVA_HOME=$(java_home -Fv 10 || java_home -Fv 9* ) && ./gradlew --stacktrace clean test )"
- "( xcodebuild -workspace platform-darwin/MasterPassword.xcworkspace -configuration 'Test' -scheme 'MasterPassword iOS' -sdk iphonesimulator clean build )"
- "( xcodebuild -workspace platform-darwin/MasterPassword.xcworkspace -configuration 'Test' -scheme 'MasterPassword macOS' clean build )"
- "( ./gradlew --stacktrace --info clean test )"
- "( cd platform-darwin && pod install )"
- "( xcodebuild -workspace platform-darwin/MasterPassword.xcworkspace -configuration 'Release' -scheme 'MasterPassword iOS' -sdk iphonesimulator clean build )"
- "( xcodebuild -workspace platform-darwin/MasterPassword.xcworkspace -configuration 'Release' -scheme 'MasterPassword macOS' clean build )"
tags:
- brew
- java_9
- xcode_9
- java
- cocoapods
- xcode

View File

@@ -49,7 +49,6 @@
93D39A5FF670957C0AF8298D /* MPSiteCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DEA995041A13DC9CAF7 /* MPSiteCell.m */; };
93D39A8EA1C49CE43B63F47B /* PearlUICollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D8A953779B35403AF6E /* PearlUICollectionView.m */; };
93D39AA4A0BE66A872CCC02E /* NSPersistentStore+PearlMigration.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D397F4BAFFF7CF3F1B21A4 /* NSPersistentStore+PearlMigration.h */; };
93D39B429C67A62E29DC02DA /* MPRootSegue.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D399493FEDDE74DD1A0C15 /* MPRootSegue.m */; };
93D39B76DD5AB108BA8928E8 /* UIScrollView+PearlAdjustInsets.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D39DE2CB351D4E3789462B /* UIScrollView+PearlAdjustInsets.h */; };
93D39B842AB9A5D072810D76 /* NSError+PearlFullDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D398C95847261903D781D3 /* NSError+PearlFullDescription.h */; };
93D39B8F90F58A5D158DDBA3 /* MPSitesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3924EE15017F8A12CB436 /* MPSitesViewController.m */; };
@@ -476,7 +475,6 @@
93D391943675426839501BB8 /* MPLogsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPLogsViewController.h; sourceTree = "<group>"; };
93D391AA32F24290C424438E /* NSNotificationCenter+PearlEasyCleanup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+PearlEasyCleanup.h"; sourceTree = "<group>"; };
93D39246FC21C6E63E35D615 /* UICollectionView+PearlReloadItems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UICollectionView+PearlReloadItems.h"; sourceTree = "<group>"; };
93D3924D6F77E6BF41AC32D3 /* MPRootSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPRootSegue.h; sourceTree = "<group>"; };
93D3924EE15017F8A12CB436 /* MPSitesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSitesViewController.m; sourceTree = "<group>"; };
93D392876BE5C011DE73B43F /* MPPopdownSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPopdownSegue.h; sourceTree = "<group>"; };
93D392C5A6572DB0EB5B82C8 /* mpw-types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "mpw-types.c"; sourceTree = "<group>"; };
@@ -505,7 +503,6 @@
93D398C95847261903D781D3 /* NSError+PearlFullDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+PearlFullDescription.h"; sourceTree = "<group>"; };
93D3990D850D76A94C6B7A4D /* mpw-algorithm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "mpw-algorithm.h"; sourceTree = "<group>"; };
93D3990E0CD1B5CF9FBB2C07 /* MPWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPWebViewController.m; sourceTree = "<group>"; };
93D399493FEDDE74DD1A0C15 /* MPRootSegue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPRootSegue.m; sourceTree = "<group>"; };
93D3995B1D4DCE5A30D882BA /* MPCoachmarkViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCoachmarkViewController.m; sourceTree = "<group>"; };
93D39975CE5AEC99E3F086C7 /* MPSiteCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteCell.h; sourceTree = "<group>"; };
93D3999693660C89A7465F4E /* MPCoachmarkViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCoachmarkViewController.h; sourceTree = "<group>"; };
@@ -2784,8 +2781,6 @@
93D39B050DD5F55E9794EFD4 /* MPPopdownSegue.m */,
DABD3BEA1711E2DC00CF925C /* MPPreferencesViewController.h */,
DABD3BEB1711E2DC00CF925C /* MPPreferencesViewController.m */,
93D3924D6F77E6BF41AC32D3 /* MPRootSegue.h */,
93D399493FEDDE74DD1A0C15 /* MPRootSegue.m */,
93D39730673227EFF6DEFF19 /* MPSetupViewController.h */,
93D39A28369954D147E239BA /* MPSetupViewController.m */,
93D39975CE5AEC99E3F086C7 /* MPSiteCell.h */,
@@ -3642,7 +3637,6 @@
93D399D7E08A142776A74CB8 /* MPOverlayViewController.m in Sources */,
DA46021D23D5E30B00398FF4 /* MPSecrets.m in Sources */,
93D39A27F2506C6FEEF9C588 /* MPAlgorithmV2.m in Sources */,
93D39B429C67A62E29DC02DA /* MPRootSegue.m in Sources */,
93D392FD5E2052F7D7DB3774 /* NSString+MPMarkDown.m in Sources */,
93D395B715D15F2B56F2A2EE /* mpw-types.c in Sources */,
93D39943D01E70DAC3B0DF76 /* mpw-util.c in Sources */,

View File

@@ -73,6 +73,13 @@
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
<EnvironmentVariables>
<EnvironmentVariable
key = "TERM"
value = "color"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"

View File

@@ -59,6 +59,17 @@
ReferencedContainer = "container:MasterPassword-macOS.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "TERM"
value = "color"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"

View File

@@ -59,6 +59,17 @@
ReferencedContainer = "container:MasterPassword-macOS.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "TERM"
value = "color"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@@ -85,6 +85,13 @@
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
<EnvironmentVariables>
<EnvironmentVariable
key = "TERM"
value = "color"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@@ -60,6 +60,17 @@
ReferencedContainer = "container:MasterPassword-macOS.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "TERM"
value = "color"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"

View File

@@ -28,3 +28,14 @@ target 'MasterPassword-macOS' do
pod 'KCOrderedAccessorFix'
pod 'JRSwizzle'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == 'Countly-iOS' || target.name == 'Countly-macOS'
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)']
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'COUNTLY_EXCLUDE_IDFA=1'
end
end
end
end

View File

@@ -621,7 +621,7 @@ static NSOperationQueue *_mpwQueue = nil;
- (NSString *)exportLoginForSite:(MPSiteEntity *)site usingKey:(MPKey *)key {
if (!(site.type & MPSiteFeatureExportContent) || site.loginGenerated || ![site.loginName length])
if (site.loginGenerated || ![site.loginName length])
return nil;
__block NSData *state = nil;

View File

@@ -201,6 +201,7 @@
}
@try {
[SentrySDK setUser:[[SentryUser alloc] initWithUserId:user.userID]];
[Countly.sharedInstance userLoggedIn:user.userID];
[Countly.sharedInstance recordEvent:@"login" segmentation:@{

View File

@@ -116,9 +116,8 @@ static MPAppDelegate_Shared *instance;
if (self.activeUserOID == activeUserOID || [self.activeUserOID isEqual:activeUserOID])
return;
if (self.key)
self.key = nil;
self.key = nil;
[SentrySDK setUser:nil];
[Countly.sharedInstance userLoggedOut];
self.activeUserOID = activeUserOID;

View File

@@ -713,23 +713,31 @@ PearlAssociatedObjectProperty( NSNumber*, StoreCorrupted, storeCorrupted );
MPMarshalledFile *exportFile = NULL;
@try {
inf( @"Exporting sites, %@, for user: %@", revealPasswords? @"revealing passwords": @"omitting passwords", user.userID );
NSString *masterPassword = askExportPassword( user.name );
if (!masterPassword) {
inf( @"Export cancelled." );
return nil;
}
MPKey *key = [[MPKey alloc] initForFullName:user.name withMasterPassword:masterPassword];
exportUser = mpw_marshal_user( user.name.UTF8String,
mpw_masterKeyProvider_str( askExportPassword( user.name ).UTF8String ), user.algorithm.version );
mpw_masterKeyProvider_str( masterPassword.UTF8String ), user.algorithm.version );
exportUser->redacted = !revealPasswords;
exportUser->avatar = (unsigned int)user.avatar;
exportUser->keyID = mpw_strdup( [user.keyID encodeHex].UTF8String );
exportUser->defaultType = user.defaultType;
exportUser->lastUsed = (time_t)user.lastUsed.timeIntervalSince1970;
for (MPSiteEntity *site in user.sites) {
for (MPSiteEntity *site in [user.sites sortedArrayUsingDescriptors:@[
[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]
]]) {
MPCounterValue counter = MPCounterValueInitial;
if ([site isKindOfClass:[MPGeneratedSiteEntity class]])
counter = ((MPGeneratedSiteEntity *)site).counter;
MPMarshalledSite *exportSite = mpw_marshal_site( exportUser,
site.name.UTF8String, site.type, counter, site.algorithm.version );
exportSite->resultState = mpw_strdup( [site.algorithm exportPasswordForSite:site usingKey:self.key].UTF8String );
exportSite->loginState = mpw_strdup( [site.algorithm exportLoginForSite:site usingKey:self.key].UTF8String );
exportSite->loginType = site.loginGenerated? MPResultTypeTemplateName: MPResultTypeStatefulPersonal;
MPMarshalledSite *exportSite = mpw_marshal_site( exportUser, site.name.UTF8String, site.type, counter, site.algorithm.version );
exportSite->resultState = mpw_strdup( [site.algorithm exportPasswordForSite:site usingKey:key].UTF8String );
exportSite->loginState = mpw_strdup( [site.algorithm exportLoginForSite:site usingKey:key].UTF8String );
exportSite->loginType = site.loginGenerated || !exportSite->loginState? MPResultTypeTemplateName: MPResultTypeStatefulPersonal;
exportSite->url = mpw_strdup( site.url.UTF8String );
exportSite->uses = (unsigned int)site.uses;
exportSite->lastUsed = (time_t)site.lastUsed.timeIntervalSince1970;

View File

@@ -41,7 +41,7 @@ __END_DECLS
\
if (__error && [[MPConfig get].sendInfo boolValue]) { \
SentryEvent *event = [[SentryEvent alloc] initWithLevel:kSentryLevelError]; \
event.message = strf(@"%@: %@", message_, [__error localizedDescription]); \
event.message = strf( message_ @": %@", ##__VA_ARGS__, [__error localizedDescription]); \
event.logger = @"MPError"; \
[SentrySDK captureEvent:event]; \
} \

View File

@@ -68,7 +68,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
@try {
// Sentry
[SentrySDK initWithOptions:@{
[SentrySDK startWithOptions:@{
@"dsn" : NilToNSNull( decrypt( sentryDSN ) ),
#ifdef DEBUG
@"debug" : @(YES),
@@ -80,7 +80,7 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
@"debug" : @(NO),
@"environment" : @"Private",
#endif
@"enabled" : [MPMacConfig get].sendInfo,
@"enabled" : @([[MPMacConfig get].sendInfo boolValue] || ![[MPMacConfig get].sendInfoDecided boolValue]),
@"enableAutoSessionTracking": @(YES),
}];
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
@@ -546,15 +546,6 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
return;
}
if (!self.key) {
NSAlert *alert = [NSAlert new];
alert.messageText = @"User Locked";
alert.informativeText = @"To export your sites, first unlock your user by opening Master Password.";
[alert runModal];
[self showPopup:nil];
return;
}
NSDateFormatter *exportDateFormatter = [NSDateFormatter new];
[exportDateFormatter setDateFormat:@"yyyy'-'MM'-'dd"];
@@ -579,43 +570,46 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
if ([savePanel runModal] == NSFileHandlingPanelCancelButton)
return;
[self exportSitesRevealPasswords:revealPasswords
askExportPassword:^NSString *(NSString *userName) {
return PearlMainQueueAwait( ^id {
NSAlert *alert = [NSAlert new];
[alert addButtonWithTitle:@"Import"];
[alert addButtonWithTitle:@"Cancel"];
alert.messageText = strf( @"Master Password For\n%@", userName );
alert.informativeText = @"Enter the current master password for this user.";
alert.accessoryView = [[NSSecureTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )];
[alert layout];
if ([alert runModal] == NSAlertFirstButtonReturn)
return ((NSTextField *)alert.accessoryView).stringValue;
else
return nil;
} );
} result:^(NSString *mpsites, NSError *error) {
if (!mpsites || error) {
PearlMainQueue( ^{
[[NSAlert alertWithError:MPError( error, @"Failed to export mpsites." )] runModal];
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
NSError *error = nil;
NSString *exportedUser = [self exportSitesFor:[self activeUserInContext:context] revealPasswords:revealPasswords askExportPassword:
^NSString *(NSString *userName) {
return PearlMainQueueAwait( ^id {
NSAlert *alert = [NSAlert new];
[alert addButtonWithTitle:@"Export"];
[alert addButtonWithTitle:@"Cancel"];
alert.messageText = strf( @"Master Password For\n%@", userName );
alert.informativeText = @"Enter the current master password for this user.";
alert.accessoryView = [[NSSecureTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )];
[alert layout];
if ([alert runModal] == NSAlertFirstButtonReturn)
return ((NSTextField *)alert.accessoryView).stringValue;
else
return nil;
} );
return;
}
} error:&error];
NSError *coordinateError = nil;
[[[NSFileCoordinator alloc] initWithFilePresenter:nil]
coordinateWritingItemAtURL:savePanel.URL options:0 error:&coordinateError byAccessor:^(NSURL *newURL) {
NSError *writeError = nil;
if (![mpsites writeToURL:newURL atomically:NO encoding:NSUTF8StringEncoding error:&writeError])
PearlMainQueue( ^{
[[NSAlert alertWithError:MPError( writeError, @"Could not write to the export file." )] runModal];
} );
}];
if (coordinateError)
PearlMainQueue( ^{
[[NSAlert alertWithError:MPError( coordinateError, @"Could not gain access to the export file." )] runModal];
} );
}];
if (error)
PearlMainQueue( ^{
[[NSAlert alertWithError:MPError( error, @"Failed to export mpsites." )] runModal];
} );
if (!exportedUser)
return;
NSError *coordinateError = nil;
[[[NSFileCoordinator alloc] initWithFilePresenter:nil]
coordinateWritingItemAtURL:savePanel.URL options:0 error:&coordinateError byAccessor:^(NSURL *newURL) {
NSError *writeError = nil;
if (![exportedUser writeToURL:newURL atomically:NO encoding:NSUTF8StringEncoding error:&writeError])
PearlMainQueue( ^{
[[NSAlert alertWithError:MPError( writeError, @"Could not write to the export file." )] runModal];
} );
}];
if (coordinateError)
PearlMainQueue( ^{
[[NSAlert alertWithError:MPError( coordinateError, @"Could not gain access to the export file." )] runModal];
} );
}];
}
- (void)updateUsers {
@@ -769,13 +763,9 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
// Send info
NSArray *countlyFeatures = @[
CLYConsentEvents, CLYConsentUserDetails, CLYConsentCrashReporting, CLYConsentViewTracking, CLYConsentStarRating
CLYConsentSessions, CLYConsentEvents, CLYConsentUserDetails, CLYConsentCrashReporting, CLYConsentViewTracking, CLYConsentStarRating
];
if ([[MPConfig get].sendInfo boolValue] || ![[MPConfig get].sendInfoDecided boolValue])
[Countly.sharedInstance giveConsentForFeature:CLYConsentSessions];
else
[Countly.sharedInstance cancelConsentForFeature:CLYConsentSessions];
if ([[MPMacConfig get].sendInfo boolValue]) {
if ([[MPMacConfig get].sendInfo boolValue] || ![[MPMacConfig get].sendInfoDecided boolValue]) {
if ([PearlLogger get].printLevel > PearlLogLevelInfo)
[PearlLogger get].printLevel = PearlLogLevelInfo;

View File

@@ -179,7 +179,8 @@
if (algorithmVersion == self.algorithm.version)
return;
[self willChangeValueForKey:@"outdated"];
self.algorithm = MPAlgorithmForVersion( algorithmVersion )?: self.algorithm;
self.algorithm =
MPAlgorithmForVersion( MIN( MPAlgorithmVersionLast, MAX( MPAlgorithmVersionFirst, algorithmVersion ) ) )?: self.algorithm;
[self didChangeValueForKey:@"outdated"];
if (self.entityOID)

View File

@@ -18,6 +18,7 @@
#import <QuartzCore/QuartzCore.h>
#import <Countly/Countly.h>
#import <UserNotifications/UserNotifications.h>
#import "MPSitesWindowController.h"
#import "MPMacAppDelegate.h"
#import "MPAppDelegate_Store.h"
@@ -52,13 +53,10 @@
if (![[MPMacConfig get].sendInfoDecided boolValue]) {
NSAlert *alert = [NSAlert new];
alert.messageText = @"Welcome to Master Password!";
alert.informativeText = @"We want you to have a top-notch experience.\n"
@"Using diagnostics, we ensure the application keeps working as designed for you.\n"
@"\n"
@"We look out for application bugs, runtime issues, sudden crashes & usage counters.\n"
@"Needless to say, diagnostics are always scrubbed and personal details will never leave your device.";
[alert addButtonWithTitle:@"Thanks!"];
alert.messageText = @"Diagnostics";
alert.informativeText = @"We look for bugs, sudden crashes, runtime issues & statistics.\n\n"
@"Diagnostics are scrubbed and personal details will never leave your device.";
[alert addButtonWithTitle:@"Engage"];
[alert addButtonWithTitle:@"Disable"];
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
[MPMacConfig get].sendInfo = @(returnCode != NSAlertSecondButtonReturn);
@@ -99,7 +97,16 @@
self.siteTable.superview.superview.layer.mask = self.siteGradient;
self.siteTable.controller = self;
prof_finish( @"ui" );
prof_rewind( @"ui" );
if (@available( macOS 10.14, * )) {
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:UNAuthorizationOptionAlert completionHandler:^(BOOL granted, NSError *error) {
if (!granted)
err( @"Couldn't obtain notification authorization: %@", error );
}];
}
prof_finish( @"notifications" );
}
- (void)dealloc {
@@ -550,13 +557,19 @@
[self copyContent:self.shiftPressed? selectedSite.loginName: selectedSite.content];
[NSApp hide:nil];
NSUserNotification *notification = [NSUserNotification new];
notification.title = @"Password Copied";
if (selectedSite.loginName.length)
notification.subtitle = strf( @"%@ at %@", selectedSite.loginName, selectedSite.name );
else
notification.subtitle = selectedSite.name;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
if (@available( macOS 10.14, * )) {
UNMutableNotificationContent *notification = [UNMutableNotificationContent new];
notification.title = self.shiftPressed? @"Login Copied": @"Password Copied";
if (selectedSite.loginName.length)
notification.subtitle = strf( @"%@ at %@", selectedSite.loginName, selectedSite.name );
else
notification.subtitle = selectedSite.name;
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:
[UNNotificationRequest requestWithIdentifier:selectedSite.name content:notification trigger:nil]
withCompletionHandler:^(NSError *error) {
dbg( @"notification: %@, completed w/errror: %@", notification, error );
}];
}
}
- (void)updateUser {

View File

@@ -722,7 +722,7 @@ Use the arrows ⇅ to navigate the list or esc ⎋ to exit.</string>
<shadow key="shadow">
<color key="color" name="controlLightHighlightColor" catalog="System" colorSpace="catalog"/>
</shadow>
<stepperCell key="cell" continuous="YES" alignment="left" minValue="1" maxValue="1000" doubleValue="1" id="73y-03-zHt"/>
<stepperCell key="cell" continuous="YES" alignment="left" maxValue="4294967295" doubleValue="1" valueWraps="YES" id="73y-03-zHt"/>
<connections>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.algorithmVersion" id="GyA-hK-6cD"/>
</connections>
@@ -776,7 +776,7 @@ Use the arrows ⇅ to navigate the list or esc ⎋ to exit.</string>
<shadow key="shadow">
<color key="color" name="controlLightHighlightColor" catalog="System" colorSpace="catalog"/>
</shadow>
<stepperCell key="cell" continuous="YES" alignment="left" minValue="1" maxValue="1000" doubleValue="1" id="ikF-n4-xiI"/>
<stepperCell key="cell" continuous="YES" alignment="left" minValue="1" maxValue="4294967295" doubleValue="1" valueWraps="YES" id="ikF-n4-xiI"/>
<connections>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.counter" id="qmm-6z-boy"/>
</connections>

View File

@@ -31,7 +31,6 @@
[super viewDidLoad];
self.mode = MPCombinedModeUserSelection;
[self performSegueWithIdentifier:@"users" sender:self];
}
- (void)viewWillAppear:(BOOL)animated {

View File

@@ -33,13 +33,6 @@
self.dismissSegueByButton = [NSMutableDictionary dictionary];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self performSegueWithIdentifier:@"root" sender:self];
}
- (UIViewController *)childViewControllerForStatusBarStyle {
return [self.childViewControllers lastObject];

View File

@@ -1,23 +0,0 @@
//==============================================================================
// This file is part of Master Password.
// Copyright (c) 2011-2017, Maarten Billemont.
//
// Master Password is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Master Password is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You can find a copy of the GNU General Public License in the
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//==============================================================================
#import <Foundation/Foundation.h>
@interface MPRootSegue : UIStoryboardSegue
@end

View File

@@ -1,35 +0,0 @@
//==============================================================================
// This file is part of Master Password.
// Copyright (c) 2011-2017, Maarten Billemont.
//
// Master Password is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Master Password is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You can find a copy of the GNU General Public License in the
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//==============================================================================
#import "MPRootSegue.h"
@implementation MPRootSegue
- (void)perform {
UIViewController *sourceViewController = self.sourceViewController;
UIViewController *destinationViewController = self.destinationViewController;
[sourceViewController addChildViewController:destinationViewController];
destinationViewController.view.frame = sourceViewController.view.bounds;
destinationViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[sourceViewController.view addSubview:destinationViewController.view];
[destinationViewController didMoveToParentViewController:sourceViewController];
[sourceViewController setNeedsStatusBarAppearanceUpdate];
}
@end

View File

@@ -263,6 +263,7 @@
UIAlertController *controller = [UIAlertController alertControllerWithTitle:strf( @"Delete %@?", site.name ) message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[controller.popoverPresentationController setSourceView:sender];
[controller addAction:[UIAlertAction actionWithTitle:@"Delete Site" style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) {
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
@@ -284,6 +285,7 @@
MPSiteEntity *mainSite = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Change Password Type" message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[controller.popoverPresentationController setSourceView:sender];
for (NSNumber *typeNumber in [mainSite.algorithm allTypes]) {
MPResultType type = (MPResultType)[typeNumber unsignedIntegerValue];
NSString *typeName = [mainSite.algorithm nameOfType:type];
@@ -425,7 +427,7 @@
if (!site || ![site isKindOfClass:[MPGeneratedSiteEntity class]])
return;
((MPGeneratedSiteEntity *)site).counter = 1;
((MPGeneratedSiteEntity *)site).counter = MPCounterValueInitial;
[context saveToStore];
[PearlOverlay showTemporaryOverlayWithTitle:@"Counter Reset" dismissAfter:2];
@@ -444,6 +446,7 @@
UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Create Site" message:
strf( @"Remember site named:\n%@", self.transientSite )
preferredStyle:UIAlertControllerStyleActionSheet];
[controller.popoverPresentationController setSourceView:sender];
[controller addAction:[UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:
^(UIAlertAction *_Nonnull action) {
[[MPiOSAppDelegate get]

View File

@@ -43,7 +43,7 @@
UIView *sitesView = sitesVC.view;
sitesView.frame = combinedVC.view.bounds;
sitesView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[combinedVC.view insertSubview:sitesView belowSubview:combinedVC.usersVC.view];
[combinedVC.view insertSubview:sitesView belowSubview:combinedVC.usersVC.view.superview];
[sitesVC setActive:YES animated:self.animated completion:^(BOOL finished) {
if (!finished)

View File

@@ -432,6 +432,7 @@ referenceSizeForFooterInSection:(NSInteger)section {
NSManagedObjectID *userID = user.permanentObjectID;
UIAlertController *controller = [UIAlertController alertControllerWithTitle:user.name message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[controller.popoverPresentationController setSourceView:avatarCell];
[controller addAction:[UIAlertAction actionWithTitle:@"Delete User" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
UIAlertController *controller_ = [UIAlertController alertControllerWithTitle:@"Deleting User" message:
@"The user and its sites will be deleted." preferredStyle:UIAlertControllerStyleAlert];

View File

@@ -57,7 +57,7 @@
@try {
// Sentry
[SentrySDK initWithOptions:@{
[SentrySDK startWithOptions:@{
@"dsn" : NilToNSNull( decrypt( sentryDSN ) ),
#ifdef DEBUG
@"debug" : @(YES),
@@ -69,7 +69,7 @@
@"debug" : @(NO),
@"environment" : @"Private",
#endif
@"enabled" : [MPiOSConfig get].sendInfo,
@"enabled" : @([[MPiOSConfig get].sendInfo boolValue] || ![[MPiOSConfig get].sendInfoDecided boolValue]),
@"enableAutoSessionTracking": @(YES),
}];
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
@@ -190,8 +190,8 @@
[migrateVC loadProductWithParameters:@{
SKStoreProductParameterCampaignToken : @"app-masterpassword.ios", /* Campaign: From MasterPassword iOS */
SKStoreProductParameterProviderToken : @153897, /* Provider: Maarten Billemont */
SKStoreProductParameterITunesItemIdentifier: @510296984, /* Application: MasterPassword iOS */
//SKStoreProductParameterITunesItemIdentifier: @1500430196, /* Application: Volto iOS */
// SKStoreProductParameterITunesItemIdentifier: @510296984, /* Application: MasterPassword iOS */
SKStoreProductParameterITunesItemIdentifier: @1500430196, /* Application: Volto iOS */
} completionBlock:^(BOOL result, NSError *error) {
if (error)
err( @"Failed loading Volto product information: %@", error );
@@ -205,7 +205,6 @@
}];
PearlMainQueueOperation( ^{
[self.navigationController performSegueWithIdentifier:@"web" sender:[NSURL URLWithString:@"masterpassword://foo?bar=quux"]];
if ([[MPiOSConfig get].showSetup boolValue])
[self.navigationController performSegueWithIdentifier:@"setup" sender:self];
@@ -598,7 +597,7 @@
@"Would you like to make all your passwords visible in the export file?\n\n"
@"A safe export will include all sites but make their passwords invisible.\n"
@"It is great as a backup and remains safe when fallen in the wrong hands."
preferredStyle:UIAlertControllerStyleActionSheet];
preferredStyle:UIAlertControllerStyleAlert];
[sheet addAction:[UIAlertAction actionWithTitle:@"Safe Export" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self showExportRevealPasswords:NO forVC:viewController];
}]];
@@ -626,35 +625,40 @@
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
NSError *error = nil;
NSString *exportedUser = [self exportSitesFor:[self activeUserInContext:context] revealPasswords:revealPasswords askExportPassword:^NSString *(NSString *userName) {
return PearlAwait( ^(void (^setResult)(id)) {
PearlMainQueue( ^{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:strf( @"Master Password For:\n%@", userName )
message:@"Enter your master password to export the user."
preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.secureTextEntry = YES;
}];
[alert addAction:[UIAlertAction actionWithTitle:@"Export" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
setResult( alert.textFields.firstObject.text );
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
setResult( nil );
}]];
[self.navigationController presentViewController:alert animated:YES completion:nil];
} );
} );
} error:&error];
NSString *exportedUser = [self exportSitesFor:[self activeUserInContext:context] revealPasswords:revealPasswords askExportPassword:
^NSString *(NSString *userName) {
return PearlAwait( ^(void (^setResult)(id)) {
PearlMainQueue( ^{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:strf(
@"Master Password For:\n%@", userName )
message:@"Enter your master password to export the user."
preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.secureTextEntry = YES;
}];
[alert addAction:[UIAlertAction actionWithTitle:@"Export" style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
setResult( alert.textFields.firstObject.text );
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
setResult( nil );
}]];
[self.navigationController presentViewController:alert animated:YES completion:nil];
} );
} );
} error:&error];
PearlMainQueue( ^{
if (!exportedUser || error) {
if (error) {
MPError( error, @"Failed to export mpsites." );
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Export Error" message:[error localizedDescription]
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Okay" style:UIAlertActionStyleCancel handler:nil]];
[self.navigationController presentViewController:alert animated:YES completion:nil];
return;
}
if (!exportedUser)
return;
NSDateFormatter *exportDateFormatter = [NSDateFormatter new];
[exportDateFormatter setDateFormat:@"yyyy'-'MM'-'dd"];
@@ -662,7 +666,7 @@
[self activeUserForMainThread].name, [exportDateFormatter stringFromDate:[NSDate date]] );
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Export Destination" message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Send As E-Mail" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
NSString *message;
if (revealPasswords)
@@ -724,7 +728,7 @@
UIAlertController *usersSheet = [UIAlertController alertControllerWithTitle:@"Migrate User"
message:@"Choose a user to migrate out to Volto."
preferredStyle:UIAlertControllerStyleActionSheet];
preferredStyle:UIAlertControllerStyleAlert];
[usersSheet addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
for (MPUserEntity *user_ in users)
[usersSheet addAction:[UIAlertAction actionWithTitle:user_.name style:UIAlertActionStyleDefault handler:
@@ -759,15 +763,16 @@
} error:&error];
PearlMainQueue( ^{
if (!exportedUser || error) {
if (error) {
MPError( error, @"Failed to export user." );
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Export Error"
message:[error localizedDescription]
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Okay" style:UIAlertActionStyleCancel handler:nil]];
[self.navigationController presentViewController:alert animated:YES completion:nil];
return;
}
if (!exportedUser)
return;
NSURLComponents *components = [NSURLComponents new];
components.scheme = @"volto";
@@ -835,20 +840,16 @@
// Send info
NSArray *countlyFeatures = @[
CLYConsentEvents, CLYConsentUserDetails, CLYConsentCrashReporting, CLYConsentViewTracking, CLYConsentStarRating
CLYConsentSessions, CLYConsentEvents, CLYConsentUserDetails, CLYConsentCrashReporting, CLYConsentViewTracking, CLYConsentStarRating
];
if ([[MPConfig get].sendInfo boolValue] || ![[MPConfig get].sendInfoDecided boolValue])
[Countly.sharedInstance giveConsentForFeature:CLYConsentSessions];
else
[Countly.sharedInstance cancelConsentForFeature:CLYConsentSessions];
if ([[MPConfig get].sendInfo boolValue]) {
if ([[MPiOSConfig get].sendInfo boolValue] || ![[MPiOSConfig get].sendInfoDecided boolValue]) {
if ([PearlLogger get].printLevel > PearlLogLevelInfo)
[PearlLogger get].printLevel = PearlLogLevelInfo;
[SentrySDK.currentHub getClient].options.enabled = @YES;
[SentrySDK configureScope:^(SentryScope *scope) {
[scope setExtraValue:[MPConfig get].rememberLogin forKey:@"rememberLogin"];
[scope setExtraValue:[MPConfig get].sendInfo forKey:@"sendInfo"];
[scope setExtraValue:[MPiOSConfig get].rememberLogin forKey:@"rememberLogin"];
[scope setExtraValue:[MPiOSConfig get].sendInfo forKey:@"sendInfo"];
[scope setExtraValue:[MPiOSConfig get].helpHidden forKey:@"helpHidden"];
[scope setExtraValue:[MPiOSConfig get].showSetup forKey:@"showQuickStart"];
[scope setExtraValue:[PearlConfig get].firstRun forKey:@"firstRun"];
@@ -865,9 +866,8 @@
#else
[scope setExtraValue:@(NO) forKey:@"reviewedVersion"];
#endif
[Countly.sharedInstance giveConsentForFeatures:countlyFeatures];
}];
[Countly.sharedInstance giveConsentForFeatures:countlyFeatures];
}
else {
[Countly.sharedInstance cancelConsentForFeatures:countlyFeatures];

View File

@@ -33,8 +33,8 @@
NSStringFromSelector( @selector( siteInfoHidden ) ) : @YES,
NSStringFromSelector( @selector( showSetup ) ) : @YES,
NSStringFromSelector( @selector( appleID ) ) : @"510296984",
NSStringFromSelector( @selector( actionsTipShown ) ) : @(!self.firstRun),
NSStringFromSelector( @selector( typeTipShown ) ) : @(!self.firstRun),
NSStringFromSelector( @selector( actionsTipShown ) ) : @(![self.firstRun boolValue]),
NSStringFromSelector( @selector( typeTipShown ) ) : @(![self.firstRun boolValue]),
NSStringFromSelector( @selector( loginNameTipShown ) ): @NO,
NSStringFromSelector( @selector( traceMode ) ) : @NO,
NSStringFromSelector( @selector( dictationSearch ) ) : @NO,

View File

@@ -3,7 +3,7 @@
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16086"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<customFonts key="customFonts">
@@ -69,7 +69,7 @@
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPAvatarCell" id="Zab-uQ-uk9" customClass="MPAvatarCell">
<rect key="frame" x="80" y="114.5" width="215" height="667"/>
<rect key="frame" x="80" y="115" width="215" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="215" height="667"/>
@@ -442,21 +442,12 @@
<outlet property="nextAvatarButton" destination="fUK-gJ-NRE" id="5qo-lK-rSa"/>
<outlet property="preferencesTipContainer" destination="0Um-Ot-hI6" id="Cv8-Bp-ZZs"/>
<outlet property="previousAvatarButton" destination="9u7-pu-Wtv" id="Hgv-lN-S1n"/>
<outlet property="searchDisplayController" destination="h98-GT-FoS" id="VvS-JO-rqq"/>
<outlet property="storeLoadingActivity" destination="VDd-oM-ZOO" id="MJ7-2f-e8n"/>
<outlet property="thanksTipContainer" destination="069-Pu-yXe" id="wWf-2X-Ryw"/>
<outlet property="userSelectionContainer" destination="rWM-08-aab" id="Yme-hX-8P0"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="8hZ-Tb-wZw" userLabel="First Responder" sceneMemberID="firstResponder"/>
<searchDisplayController id="h98-GT-FoS">
<connections>
<outlet property="delegate" destination="S8q-YF-Kt9" id="hyY-rf-2x2"/>
<outlet property="searchContentsController" destination="S8q-YF-Kt9" id="2RA-rs-GhH"/>
<outlet property="searchResultsDataSource" destination="S8q-YF-Kt9" id="Cdu-go-UBQ"/>
<outlet property="searchResultsDelegate" destination="S8q-YF-Kt9" id="xxe-xE-sFM"/>
</connections>
</searchDisplayController>
</objects>
<point key="canvasLocation" x="2041" y="226"/>
</scene>
@@ -531,12 +522,23 @@
<view key="view" contentMode="scaleToFill" id="c4P-nn-PjR">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qca-aL-Un8">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<connections>
<segue destination="Ac5-na-hOV" kind="embed" identifier="root" id="x4h-Hl-KXD"/>
</connections>
</containerView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="qca-aL-Un8" firstAttribute="top" secondItem="c4P-nn-PjR" secondAttribute="top" id="7ix-Oo-ELN"/>
<constraint firstAttribute="bottom" secondItem="qca-aL-Un8" secondAttribute="bottom" id="JRU-fk-cPG"/>
<constraint firstItem="qca-aL-Un8" firstAttribute="leading" secondItem="c4P-nn-PjR" secondAttribute="leading" id="OAO-XC-DQ1"/>
<constraint firstAttribute="trailing" secondItem="qca-aL-Un8" secondAttribute="trailing" id="R9n-bd-GVl"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="V6W-ql-3TD"/>
<connections>
<segue destination="Ac5-na-hOV" kind="custom" identifier="root" customClass="MPRootSegue" id="UKS-gd-oD2"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="fQY-fV-sIe" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
@@ -557,12 +559,25 @@
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" image="background.png" translatesAutoresizingMaskIntoConstraints="NO" id="Lkg-xn-bce" userLabel="Background">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
</imageView>
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="91I-wN-JQb">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="ignoreTouches" value="YES"/>
</userDefinedRuntimeAttributes>
<connections>
<segue destination="S8q-YF-Kt9" kind="embed" identifier="users" id="GzD-Zv-DzW"/>
</connections>
</containerView>
</subviews>
<constraints>
<constraint firstItem="91I-wN-JQb" firstAttribute="leading" secondItem="fkJ-D0-yue" secondAttribute="leading" id="E4w-Dw-Vip"/>
<constraint firstItem="Lkg-xn-bce" firstAttribute="top" secondItem="fkJ-D0-yue" secondAttribute="top" id="EIy-Cd-0vW"/>
<constraint firstItem="91I-wN-JQb" firstAttribute="top" secondItem="fkJ-D0-yue" secondAttribute="top" id="EeB-9X-PEK"/>
<constraint firstAttribute="trailing" secondItem="Lkg-xn-bce" secondAttribute="trailing" id="ROW-fK-z92"/>
<constraint firstItem="Lkg-xn-bce" firstAttribute="leading" secondItem="fkJ-D0-yue" secondAttribute="leading" id="UH5-Kk-taJ"/>
<constraint firstAttribute="bottom" secondItem="91I-wN-JQb" secondAttribute="bottom" id="mxv-9s-jxT"/>
<constraint firstAttribute="bottom" secondItem="Lkg-xn-bce" secondAttribute="bottom" id="txR-pf-v3l"/>
<constraint firstAttribute="trailing" secondItem="91I-wN-JQb" secondAttribute="trailing" id="uef-ig-RRl"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="MPa-zX-Kaq"/>
@@ -570,7 +585,6 @@
<connections>
<segue destination="osn-5H-SWW" kind="custom" identifier="emergency" customClass="MPOverlaySegue" id="gtX-Cx-AA2"/>
<segue destination="nkY-z6-8jd" kind="custom" identifier="passwords" customClass="MPSitesSegue" id="Ozp-YT-Utx"/>
<segue destination="S8q-YF-Kt9" kind="custom" identifier="users" customClass="MPRootSegue" id="StK-nr-nps"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="F33-Fe-Tb6" userLabel="First Responder" sceneMemberID="firstResponder"/>

View File

@@ -151,7 +151,7 @@ public interface MPAlgorithm {
/**
* The algorithm iterations.
*/
enum Version implements MPAlgorithm {
enum Version implements MPAlgorithm {
/**
* bugs:
@@ -346,7 +346,7 @@ public interface MPAlgorithm {
@Nonnull
@Override
public Version version() {
return MPAlgorithm.Version.V0;
return this;
}
@Nonnull

View File

@@ -20,7 +20,6 @@ package com.lyndir.masterpassword;
import com.google.common.base.Preconditions;
import com.google.common.primitives.UnsignedInteger;
import com.lyndir.lhunath.opal.system.CodeUtils;
import com.lyndir.lhunath.opal.system.logging.Logger;
import java.util.Arrays;
import java.util.EnumMap;
@@ -56,6 +55,7 @@ public class MPMasterKey {
}
@Override
@SuppressWarnings("deprecation")
protected void finalize()
throws Throwable {