WIP on adding TOTP ui to entry view

This commit is contained in:
Michael Starke
2020-11-28 23:10:45 +01:00
parent 7c9460d027
commit e08b116aa0
15 changed files with 282 additions and 43 deletions

View File

@@ -1,4 +1,4 @@
github "sparkle-project/Sparkle" ~> 1.22
github "mattt/TransformerKit" ~> 1.1.1
github "MacPass/KeePassKit" "4993fc9e0f4dc7dc010c7ed9c3c54d9f1484b8f9"
github "MacPass/KeePassKit" "958637c267d29d4db59773d215d08e52b18442c0"
github "mstarke/HNHUi" ~> 4.0

View File

@@ -1,4 +1,4 @@
github "MacPass/KeePassKit" "4993fc9e0f4dc7dc010c7ed9c3c54d9f1484b8f9"
github "MacPass/KeePassKit" "958637c267d29d4db59773d215d08e52b18442c0"
github "mattt/TransformerKit" "1.1.1"
github "mstarke/HNHUi" "4.0.2"
github "robbiehanson/KissXML" "5.3.2"

View File

@@ -48,6 +48,8 @@
4C25703F1BF11C2300D39416 /* MPPluginPreferencesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C25703D1BF11C2300D39416 /* MPPluginPreferencesController.m */; };
4C25D58716CF0FAA00F6806C /* EntryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C25D58616CF0FAA00F6806C /* EntryView.xib */; };
4C26C33F18D8C92100CF1A1C /* MPTemporaryFileStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C26C33E18D8C92100CF1A1C /* MPTemporaryFileStorage.m */; };
4C2892A8257103F9003C7732 /* MPTOTPViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C2892A6257103F9003C7732 /* MPTOTPViewController.m */; };
4C2892A9257103F9003C7732 /* MPTOTPViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C2892A7257103F9003C7732 /* MPTOTPViewController.xib */; };
4C2E381D16D11FF900037A9D /* 03_ServerTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C2E381A16D11FF900037A9D /* 03_ServerTemplate.pdf */; };
4C2E381E16D11FF900037A9D /* 04_KlipperTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C2E381B16D11FF900037A9D /* 04_KlipperTemplate.pdf */; };
4C2E381F16D11FF900037A9D /* 05_LanguagesTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C2E381C16D11FF900037A9D /* 05_LanguagesTemplate.pdf */; };
@@ -433,6 +435,9 @@
4C272A292224871900186EEC /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/PluginDataView.strings; sourceTree = "<group>"; };
4C272A2A2224871900186EEC /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/OpenPanelAccessoryView.strings; sourceTree = "<group>"; };
4C272A2B2224871900186EEC /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/PickfieldView.strings; sourceTree = "<group>"; };
4C2892A5257103F9003C7732 /* MPTOTPViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPTOTPViewController.h; sourceTree = "<group>"; };
4C2892A6257103F9003C7732 /* MPTOTPViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPTOTPViewController.m; sourceTree = "<group>"; };
4C2892A7257103F9003C7732 /* MPTOTPViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MPTOTPViewController.xib; sourceTree = "<group>"; };
4C2B0B7419F66F6400E48913 /* MPTargetNodeResolving.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPTargetNodeResolving.h; sourceTree = "<group>"; };
4C2E381A16D11FF900037A9D /* 03_ServerTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 03_ServerTemplate.pdf; sourceTree = "<group>"; };
4C2E381B16D11FF900037A9D /* 04_KlipperTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = 04_KlipperTemplate.pdf; sourceTree = "<group>"; };
@@ -1380,6 +1385,9 @@
4C77547316E55FE800970E02 /* MPInspectorViewController.h */,
4C77547416E55FE800970E02 /* MPInspectorViewController.m */,
4C76156F1764C0E20015A1A6 /* InspectorView.xib */,
4C2892A5257103F9003C7732 /* MPTOTPViewController.h */,
4C2892A6257103F9003C7732 /* MPTOTPViewController.m */,
4C2892A7257103F9003C7732 /* MPTOTPViewController.xib */,
);
name = Inspector;
sourceTree = "<group>";
@@ -2037,6 +2045,7 @@
4C0DBEF51BF508DE00F9B287 /* PluginPreferences.xib in Resources */,
4CF6653820E67A140008A25C /* PluginDataView.xib in Resources */,
4C7F8B681A10B68400CCB83D /* WelcomeView.xib in Resources */,
4C2892A9257103F9003C7732 /* MPTOTPViewController.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2224,6 +2233,7 @@
4C5807781C64F67000E7171F /* NSString+MPHash.m in Sources */,
4CAAA8271D787B8B00CDE977 /* MPAutotypeBuilderViewController.m in Sources */,
4CE501341BBC47F500FB819D /* MPTagsTokenFieldDelegate.m in Sources */,
4C2892A8257103F9003C7732 /* MPTOTPViewController.m in Sources */,
4CC6DB7A17D23719002C6091 /* KPKNode+IconImage.m in Sources */,
4C15B74618BCA3B1003F8008 /* MPDocument+Search.m in Sources */,
4CEED1C617D7BD0E007180F1 /* NSError+Messages.m in Sources */,

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -47,8 +47,8 @@
<rect key="frame" x="0.0" y="0.0" width="293" height="493"/>
<subviews>
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="82">
<rect key="frame" x="56.5" y="469" width="180" height="19"/>
<segmentedCell key="cell" controlSize="small" borderStyle="border" alignment="left" style="texturedSquare" trackingMode="selectOne" id="238">
<rect key="frame" x="62" y="469" width="170" height="19"/>
<segmentedCell key="cell" controlSize="small" borderStyle="border" alignment="left" style="capsule" trackingMode="selectOne" id="238">
<font key="font" metaFont="smallSystem"/>
<segments>
<segment label="General" selected="YES"/>
@@ -73,7 +73,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="124">
<rect key="frame" x="240.5" y="427" width="33" height="23"/>
<rect key="frame" x="241" y="428" width="32" height="23"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="176"/>
</constraints>
@@ -97,18 +97,17 @@
<rect key="frame" x="20" y="26" width="253" height="396"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="F3N-QI-Di5">
<rect key="frame" x="1" y="1" width="251" height="394"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" multipleSelection="NO" autosaveColumns="NO" rowHeight="36" rowSizeStyle="automatic" viewBased="YES" id="137">
<rect key="frame" x="0.0" y="0.0" width="251" height="394"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="alternateSelectedControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="248" minWidth="40" maxWidth="1000" id="140">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
@@ -309,7 +308,7 @@
<outlet property="nextKeyView" destination="QSX-Xo-tcH" id="P9m-Wl-V3E"/>
</connections>
</segmentedControl>
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dx3-E2-FFt">
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="250" verticalStackHuggingPriority="250" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dx3-E2-FFt">
<rect key="frame" x="20" y="131" width="251" height="333"/>
<subviews>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="52">
@@ -411,8 +410,8 @@
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="57">
<rect key="frame" x="-2" y="166" width="26" height="14"/>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="57">
<rect key="frame" x="-2" y="166" width="255" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="URL" id="66">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
@@ -466,8 +465,8 @@
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6">
<rect key="frame" x="-2" y="85" width="29" height="14"/>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6">
<rect key="frame" x="-2" y="85" width="255" height="14"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Tags" id="79">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
@@ -594,14 +593,13 @@
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="caM-L6-UHC">
<rect key="frame" x="0.0" y="0.0" width="259" height="161"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="256" minWidth="40" maxWidth="1000" id="Wdn-k1-39b">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
@@ -769,21 +767,20 @@
<point key="canvasLocation" x="35" y="-993"/>
</view>
<scrollView borderType="line" autohidesScrollers="YES" horizontalLineScroll="56" horizontalPageScroll="10" verticalLineScroll="56" verticalPageScroll="10" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="180" customClass="HNHUIScrollView">
<rect key="frame" x="0.0" y="0.0" width="261" height="270"/>
<rect key="frame" x="0.0" y="0.0" width="261" height="268"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="k8G-zp-BXZ">
<rect key="frame" x="1" y="1" width="259" height="268"/>
<rect key="frame" x="1" y="1" width="259" height="266"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView focusRingType="none" verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="none" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="54" viewBased="YES" id="193">
<rect key="frame" x="0.0" y="0.0" width="259" height="268"/>
<autoresizingMask key="autoresizingMask"/>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="none" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="54" viewBased="YES" id="193">
<rect key="frame" x="0.0" y="0.0" width="259" height="266"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="256" minWidth="40" maxWidth="1000000" id="194">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
@@ -794,8 +791,8 @@
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
<prototypeCellViews>
<tableCellView identifier="SelectedCell" misplaced="YES" id="196" customClass="MPCustomFieldTableCellView">
<rect key="frame" x="1" y="1" width="256" height="54"/>
<tableCellView identifier="SelectedCell" id="196" customClass="MPCustomFieldTableCellView">
<rect key="frame" x="1" y="1" width="256" height="53"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="199" customClass="HNHUISecureTextField">

View File

@@ -83,7 +83,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2985">
<rect key="frame" x="84" y="194" width="111" height="23"/>
<rect key="frame" x="82" y="194" width="115" height="23"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="No Selection" id="2986">
<font key="font" metaFont="system" size="20"/>
<color key="textColor" name="controlShadowColor" catalog="System" colorSpace="catalog"/>

View File

@@ -10,6 +10,12 @@
NS_ASSUME_NONNULL_BEGIN
FOUNDATION_EXTERN NSString *const MPHMACOTPSeedAttributeKey;
FOUNDATION_EXTERN NSString *const MPHMACOTPConfigAttributeKey;
FOUNDATION_EXTERN NSString *const MPTOTPAuthAttributeKey;
FOUNDATION_EXTERN NSString *const MPTOTPSeedAttributeKey;
FOUNDATION_EXTERN NSString *const MPTOTPConfigAttributeKey;
@interface KPKEntry (OTP)
@property (readonly, assign, nonatomic) BOOL hasTOTP;

View File

@@ -10,12 +10,22 @@
@implementation KPKEntry (OTP)
NSString *const MPHMACOTPSeedAttributeKey = @"HMACOTP-Seed";
NSString *const MPHMACOTPConfigAttributeKey = @"HMACOTP-Config";
NSString *const MPTOTPAuthAttributeKey = @"otp";
NSString *const MPTOTPSeedAttributeKey = @"TOTP Seed";
NSString *const MPTOTPConfigAttributeKey = @"OTP Settings";
+ (NSSet<NSString *> *)keyPathsForValuesAffectingHasTOTP {
return [NSSet setWithObject:NSStringFromSelector(@selector(attributes))];
}
- (BOOL)hasTOTP {
return NO;
BOOL hasURLKey = [self hasAttributeWithKey:MPTOTPAuthAttributeKey];
BOOL hasSeedKey = [self hasAttributeWithKey:MPTOTPSeedAttributeKey];
BOOL hasSettingsKey = [self hasAttributeWithKey:MPTOTPConfigAttributeKey];
return(hasURLKey || (hasSeedKey && hasSettingsKey));
}
@end

View File

@@ -23,8 +23,7 @@
#import "MPAddCustomFieldContextMenuDelegate.h"
#import "KeePassKit/KeePassKit.h"
NSString *const MPHMACOTPSeedAttributeKey = @"HMACOTP-Seed";
NSString *const MPHMACOTPConfigAttributeKey = @"HMACOTP-Config";
#import "KPKEntry+OTP.h"
/*
HmacOtp-Secret (the UTF-8 representation of the value is the secret),
@@ -51,9 +50,11 @@ HmacOtp-Counter field.
- (void)menuNeedsUpdate:(NSMenu *)menu {
[menu removeAllItems];
//[self _setupHOTPMenuItemsToMenu:menu];
[self _setupHOTPMenuItemsToMenu:menu];
[self _setupTOTPMenuItemsToMenu:menu];
}
/* HMAC OTP */
- (void)_setupHOTPMenuItemsToMenu:(NSMenu *)menu {
BOOL hasConfigAttribute = nil != [self.entry customAttributeWithKey:MPHMACOTPConfigAttributeKey];
if(!hasConfigAttribute) {
@@ -68,6 +69,8 @@ HmacOtp-Counter field.
[menu addItem:item];
}
}
- (IBAction)_setupHMACConfig:(id)sender {}
- (IBAction)_delteHMACConfig:(id)sender {}
- (IBAction)_addHMACConfig:(id)sender {
[self.entry addCustomAttribute:[[KPKAttribute alloc] initWithKey:MPHMACOTPConfigAttributeKey value:@"<config>"]];
@@ -77,4 +80,35 @@ HmacOtp-Counter field.
[self.entry addCustomAttribute:[[KPKAttribute alloc] initWithKey:MPHMACOTPSeedAttributeKey value:@"<seed>"]];
}
/* Time OPT*/
- (void)_setupTOTPMenuItemsToMenu:(NSMenu *)menu {
BOOL hasTOTPAuthAttribute = nil != [self.entry customAttributeWithKey:MPTOTPAuthAttributeKey];
BOOL hasTOTPSeedAttribute = nil != [self.entry customAttributeWithKey:MPTOTPSeedAttributeKey];
BOOL hasTOTPSettingsAttribute = nil != [self.entry customAttributeWithKey:MPTOTPSeedAttributeKey];
BOOL hasValidSettings = hasTOTPAuthAttribute || (hasTOTPSeedAttribute && hasTOTPSettingsAttribute);
if(hasValidSettings) {
// Edit
NSMenuItem *editItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"EDIT_TOTP_SETTINGS", @"Menu item title editing TOTP settings") action:@selector(_editTOTPSettings:) keyEquivalent:@""];
editItem.target = self;
[menu addItem:editItem];
// Delete
NSMenuItem *deleteItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"DELETE_TOTP_SETTINGS", @"Menu item title for deleting TOTP settings") action:@selector(_deleteTOTPSettings:) keyEquivalent:@""];
deleteItem.target = self;
[menu addItem:deleteItem];
}
else {
// Setup
NSMenuItem *setupItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SETUP_TOTP_SETTINGS", @"Menu item title editing TOTP settings") action:@selector(_setupTOTPSettings:) keyEquivalent:@""];
setupItem.target = self;
[menu addItem:setupItem];
}
}
- (IBAction)_setupTOTPSettings:(id)sender {}
- (IBAction)_editTOTPSettings:(id)sender {}
- (IBAction)_deleteTOTPSettings:(id)sender {}
@end

View File

@@ -59,6 +59,11 @@
@property (strong) IBOutlet NSTableView *customFieldsTableView;
@property (weak) IBOutlet NSButton *showCustomDataButton;
/* TOTP */
@property (strong) IBOutlet NSProgressIndicator *totpProgressIndicator;
@property (strong) IBOutlet NSTextField *totpLabelTextField;
@property (strong) IBOutlet NSTextField *totpCodeTextField;
/* Autotype */
@property (strong) IBOutlet NSView *autotypView;
@property (weak) IBOutlet NSButton *enableAutotypeCheckButton;

View File

@@ -31,6 +31,7 @@
#import "MPTagsTokenFieldDelegate.h"
#import "MPAutotypeBuilderViewController.h"
#import "MPReferenceBuilderViewController.h"
#import "MPTOTPViewController.h"
#import "MPPrettyPasswordTransformer.h"
#import "NSString+MPPasswordCreation.h"
@@ -48,8 +49,9 @@
#import "MPArrayController.h"
#import "KeePassKit/KeePassKit.h"
#import "KPKEntry+OTP.h"
#import "KeePassKit/KeePassKit.h"
#import "HNHUi/HNHUi.h"
typedef NS_ENUM(NSUInteger, MPEntryTab) {
@@ -79,6 +81,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
@property (nonatomic, assign) BOOL showPassword;
@property (nonatomic, assign) MPEntryTab activeTab;
@property (nonatomic, readonly) KPKEntry *representedEntry;
@property (strong) MPTOTPViewController *totpViewController;
@property (strong) MPTemporaryFileStorage *quicklookStorage;
@@ -121,6 +124,11 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
return nil;
}
- (void)setRepresentedObject:(id)representedObject {
super.representedObject = representedObject;
self.totpViewController.representedObject = self.representedObject;
}
- (void)viewDidLoad {
[self _addScrollViewWithView:self.generalView atTab:MPEntryTabGeneral];
@@ -176,6 +184,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
self.tagsTokenField.delegate = _tagTokenFieldDelegate;
[self _setupTOPTView];
[self _setupCustomFieldsButton];
[self _setupViewBindings];
}
@@ -192,10 +201,6 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
object:document];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark -
#pragma mark Actions
@@ -278,8 +283,8 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
KPKWindowAssociation *association = self.representedEntry.autotype.associations[row];
if(association) {
[self.representedEntry.autotype removeAssociation:association];
[self.observer didChangeModelProperty];
}
[self.observer didChangeModelProperty];
}
}
@@ -436,7 +441,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
metrics:nil
views:views]];
[[self view] layoutSubtreeIfNeeded];
[self.view layoutSubtreeIfNeeded];
}
#pragma mark -
@@ -508,7 +513,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
withKeyPath:[NSString stringWithFormat:@"%@.%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(uuid)), NSStringFromSelector(@selector(UUIDString))]
options:@{ NSConditionallySetsEditableBindingOption: @NO }];
self.uuidTextField.editable = NO;
/* Attachments */
[_attachmentsController bind:NSContentArrayBinding
toObject:self
@@ -565,7 +570,15 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
NSMenu *customFieldMenu = [[NSMenu alloc] initWithTitle:NSLocalizedString(@"ADD_CUSTOM_FIELD_CONTEXT_MENU", @"Menu displayed for adding special custom keys")];
customFieldMenu.delegate = _addCustomFieldContextMenuDelegate;
self.addCustomFieldButton.contextMenu = customFieldMenu;
[self.addCustomFieldButton setEnabled:NO forSegment:MPContextButtonSegmentContextButton];
//[self.addCustomFieldButton setEnabled:NO forSegment:MPContextButtonSegmentContextButton];
}
- (void)_setupTOPTView {
self.totpViewController = [[MPTOTPViewController alloc] init];
NSInteger urlindex = [self.fieldsStackView.arrangedSubviews indexOfObject:self.URLTextField];
NSAssert(urlindex != NSNotFound, @"Missing reference view. This should not happen!");
[self.fieldsStackView insertArrangedSubview:self.totpViewController.view atIndex:urlindex - 1];
}
#pragma mark -
@@ -656,4 +669,10 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
self.showPassword = NO;
}
#pragma mark -
#pragma mark KPKEntry Notifications
- (void)_didChangeAttribute:(NSNotification *)notification {
}
@end

View File

@@ -76,10 +76,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
return self;
}
- (void)dealloc {
[NSNotificationCenter.defaultCenter removeObserver:self];
}
- (NSResponder *)reconmendedFirstResponder {
return self.view;
}

View File

@@ -0,0 +1,20 @@
//
// MPOTPViewController.h
// MacPass
//
// Created by Michael Starke on 27.11.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <HNHUi/HNHUi.h>
NS_ASSUME_NONNULL_BEGIN
@interface MPTOTPViewController : NSViewController
@property (strong) IBOutlet HNHUITextField *toptValueTextField;
@property (strong) IBOutlet NSProgressIndicator *remainingTimeProgressIndicator;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,20 @@
//
// MPOTPViewController.h
// MacPass
//
// Created by Michael Starke on 27.11.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <HNHUi/HNHUi.h>
NS_ASSUME_NONNULL_BEGIN
@interface MPTOTPViewController : NSViewController
@property (strong) IBOutlet HNHUITextField *toptValueTextField;
@property (strong) IBOutlet NSProgressIndicator *remainingTimeProgressIndicator;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,56 @@
//
// MPOTPViewController.m
// MacPass
//
// Created by Michael Starke on 27.11.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import "MPTOTPViewController.h"
#import "KPKEntry+OTP.h"
#import <KeePassKit/KeePassKit.h>
@interface MPTOTPViewController ()
@property (strong) KPKOTPGenerator *otpGenerator;
@end
@implementation MPTOTPViewController
- (void)viewDidLoad {
self.otpGenerator = [[KPKOTPGenerator alloc] init];
[super viewDidLoad];
}
- (void)setRepresentedObject:(id)representedObject {
NSArray *notificationNames = @[KPKWillAddAttributeNotification, KPKDidAddAttributeNotification, KPKWillChangeAttributeNotification, KPKDidChangeAttributeNotification, KPKWillRemoveAttributeNotification, KPKDidRemoveAttributeNotification];
if(self.representedObject) {
for(NSString *notificationName in notificationNames) {
[NSNotificationCenter.defaultCenter removeObserver:self name:notificationName object:self.representedObject];
}
}
super.representedObject = representedObject;
if(representedObject) {
for(NSString *notificationName in notificationNames) {
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didChangeAttribute:) name:notificationName object:representedObject];
}
}
[self _didChangeAttribute:nil];
}
- (void)_didChangeAttribute:(NSNotification *)notification {
KPKEntry *entry = (KPKEntry *)self.representedObject;
BOOL showTOTP = entry.hasTOTP;
self.view.hidden = !showTOTP;
if(showTOTP) {
self.remainingTimeProgressIndicator.indeterminate = YES;
}
else {
self.remainingTimeProgressIndicator.indeterminate = NO;
}
}
@end

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPTOTPViewController">
<connections>
<outlet property="remainingTimeProgressIndicator" destination="lSU-Q9-tC6" id="DpE-6F-yKb"/>
<outlet property="toptValueTextField" destination="xBL-Jz-VQO" id="QwC-Um-82o"/>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="480" height="69"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="250" verticalStackHuggingPriority="250" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Lz5-aM-o4b">
<rect key="frame" x="0.0" y="0.0" width="480" height="69"/>
<subviews>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r8F-6m-CG6">
<rect key="frame" x="-2" y="55" width="484" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="TOTP" id="mP4-nH-7TA">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xBL-Jz-VQO" customClass="HNHUITextField">
<rect key="frame" x="0.0" y="26" width="480" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" selectable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="Vuy-HC-UhI">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<progressIndicator wantsLayer="YES" maxValue="100" doubleValue="50" style="bar" translatesAutoresizingMaskIntoConstraints="NO" id="lSU-Q9-tC6">
<rect key="frame" x="0.0" y="-1" width="480" height="20"/>
</progressIndicator>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="Lz5-aM-o4b" secondAttribute="bottom" id="JFd-zk-sz4"/>
<constraint firstAttribute="trailing" secondItem="Lz5-aM-o4b" secondAttribute="trailing" id="vne-gZ-Ec8"/>
<constraint firstItem="Lz5-aM-o4b" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="y4i-uB-HlK"/>
<constraint firstItem="Lz5-aM-o4b" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="zFP-JZ-Qtu"/>
</constraints>
<point key="canvasLocation" x="-86" y="170"/>
</customView>
</objects>
</document>