2
0

Initial support for security questions in Mac app.

This commit is contained in:
Maarten Billemont 2016-02-20 21:56:04 -05:00
parent 0269c2741a
commit 64829c99d8
10 changed files with 157 additions and 89 deletions

View File

@ -5,7 +5,6 @@
<inspection_tool class="Convert to string" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="FunctionImplicitDeclarationInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ImplicitIntegerAndEnumConversion" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LossyEncoding" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MethodIsLaterInTheScope" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCNotLocalizedStringInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCUnusedMacroInspection" enabled="false" level="WARNING" enabled_by_default="false" />

View File

@ -22,6 +22,13 @@
@end
@interface MPSiteQuestionEntity(MP)
- (NSString *)resolveQuestionAnswerUsingKey:(MPKey *)key;
- (void)resolveQuestionAnswerUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result;
@end
@interface MPSiteEntity(MP)<MPFixable>
@property(assign) BOOL loginGenerated;
@ -38,8 +45,10 @@
- (BOOL)tryMigrateExplicitly:(BOOL)explicit;
- (NSString *)resolveLoginUsingKey:(MPKey *)key;
- (NSString *)resolvePasswordUsingKey:(MPKey *)key;
- (NSString *)resolveSiteAnswerUsingKey:(MPKey *)key;
- (void)resolveLoginUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result;
- (void)resolvePasswordUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result;
- (void)resolveSiteAnswerUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result;
@end

View File

@ -35,6 +35,20 @@
@end
@implementation MPSiteQuestionEntity(MP)
- (NSString *)resolveQuestionAnswerUsingKey:(MPKey *)key {
return [self.site.algorithm resolveAnswerForQuestion:self usingKey:key];
}
- (void)resolveQuestionAnswerUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result {
[self.site.algorithm resolveAnswerForQuestion:self usingKey:key result:result];
}
@end
@implementation MPSiteEntity(MP)
- (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context {
@ -175,6 +189,11 @@
return [self.algorithm resolvePasswordForSite:self usingKey:key];
}
- (NSString *)resolveSiteAnswerUsingKey:(MPKey *)key {
return [self.algorithm resolveAnswerForSite:self usingKey:key];
}
- (void)resolveLoginUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result {
[self.algorithm resolveLoginForSite:self usingKey:key result:result];
@ -185,6 +204,11 @@
[self.algorithm resolvePasswordForSite:self usingKey:key result:result];
}
- (void)resolveSiteAnswerUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result {
[self.algorithm resolveAnswerForSite:self usingKey:key result:result];
}
@end
@implementation MPGeneratedSiteEntity(MP)

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
</dependencies>
<objects>

View File

@ -28,6 +28,7 @@
@property(nonatomic) NSString *masterPassword;
@property(nonatomic) BOOL showVersionContainer;
@property(nonatomic) BOOL alternatePressed;
@property(nonatomic) BOOL shiftPressed;
@property(nonatomic) BOOL locked;
@property(nonatomic) BOOL newUser;

View File

@ -124,6 +124,10 @@
- (void)flagsChanged:(NSEvent *)theEvent {
BOOL shiftPressed = (theEvent.modifierFlags & NSShiftKeyMask) != 0;
if (shiftPressed != self.shiftPressed)
self.shiftPressed = shiftPressed;
BOOL alternatePressed = (theEvent.modifierFlags & NSAlternateKeyMask) != 0;
if (alternatePressed != self.alternatePressed) {
self.alternatePressed = alternatePressed;
@ -486,7 +490,7 @@
}
// Performing action while content is available. Copy it.
[self copyContent:selectedSite.content];
[self copyContent:self.shiftPressed? selectedSite.answer: selectedSite.content];
[self fadeOut];

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9059" systemVersion="15B42" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9531" systemVersion="15D21" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9059"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9531"/>
<capability name="box content view" minToolsVersion="7.0"/>
<capability name="stacking Non-gravity area distributions on NSStackView" minToolsVersion="7.0" minSystemVersion="10.11"/>
</dependencies>
@ -28,10 +28,10 @@
<window title="Master Password" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hasShadow="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="MPPasswordWindow">
<windowCollectionBehavior key="collectionBehavior" moveToActiveSpace="YES" transient="YES" ignoresCycle="YES" fullScreenAuxiliary="YES"/>
<rect key="contentRect" x="0.0" y="0.0" width="640" height="560"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="900"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ" userLabel="Root">
<rect key="frame" x="0.0" y="0.0" width="640" height="560"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Bwc-sd-6gm" userLabel="Screen Capture">
<rect key="frame" x="-80" y="-80" width="800" height="720"/>
@ -55,19 +55,16 @@
</configuration>
</ciFilter>
</contentFilters>
<animations/>
<imageCell key="cell" enabled="NO" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="small-screen" id="ArA-2w-I56"/>
</imageView>
<progressIndicator hidden="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" displayedWhenStopped="NO" bezeled="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="oSh-Ec-8Nf" userLabel="Progress Spinner">
<rect key="frame" x="312" y="524" width="16" height="16"/>
<animations/>
</progressIndicator>
<button translatesAutoresizingMaskIntoConstraints="NO" id="Aue-Zx-6Mf" userLabel="Settings Gear">
<rect key="frame" x="588" y="508" width="32" height="32"/>
<animations/>
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="icon_gear" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="i8r-9N-vcQ">
<rect key="frame" x="585" y="496" width="35" height="44"/>
<buttonCell key="cell" type="square" title="⚙" bezelStyle="shadowlessSquare" alignment="center" imageScaling="proportionallyDown" inset="2" id="i8r-9N-vcQ">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" size="48" name="AppleSymbols"/>
<string key="keyEquivalent">,</string>
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell>
@ -76,12 +73,11 @@
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gAU-xs-aae">
<rect key="frame" x="595" y="490" width="19" height="14"/>
<rect key="frame" x="593" y="478" width="19" height="14"/>
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘," id="Xm1-qb-6EP">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -101,7 +97,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" focusRingType="none" alignment="center" usesSingleLineMode="YES" id="NcX-1Z-2OC">
<font key="font" metaFont="system" size="36"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -137,7 +132,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" focusRingType="none" alignment="center" placeholderString="" usesSingleLineMode="YES" id="gRw-5C-YUN">
<font key="font" metaFont="system" size="36"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -173,7 +167,6 @@
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R46-fx-n14">
<rect key="frame" x="232" y="19" width="177" height="19"/>
<animations/>
<buttonCell key="cell" type="recessed" title="Reset My Master Password" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="B7Z-72-fVP" customClass="MPNoStateButtonCell">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
@ -193,7 +186,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.70000000000000007" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Hold alt ⌥ to temporarily reveal what you've typed." id="4Ep-xX-Ky8">
<font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -225,7 +217,6 @@
</configuration>
</ciFilter>
</contentFilters>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="KeljXoleKowi9@" placeholderString="" id="WVV-EE-tkB">
<font key="font" size="64" name="SourceCodePro-Regular"/>
<color key="textColor" name="keyboardFocusIndicatorColor" catalog="System" colorSpace="catalog"/>
@ -240,19 +231,77 @@
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.displayedContent" id="Sdg-fb-kQK"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ond-dT-x5d" userLabel="Site Password Tip">
<rect key="frame" x="220" y="146" width="160" height="14"/>
<searchField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eBx-2g-chS" userLabel="Site Question">
<rect key="frame" x="42" y="33" width="516" height="14"/>
<constraints>
<constraint firstAttribute="width" constant="512" id="JSe-85-4H0"/>
</constraints>
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" red="0.0" green="0.0" blue="0.0" alpha="0.80000000000000004" colorSpace="calibratedRGB"/>
</shadow>
<searchFieldCell key="cell" controlSize="small" selectable="YES" editable="YES" focusRingType="none" alignment="center" placeholderString="Question Keyword" sendsSearchStringImmediately="YES" id="sZN-Vi-v8k">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
<connections>
<action selector="doSearchSites:" target="-2" id="72O-59-xYV"/>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="Skr-1g-quT">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.question" id="3AM-pr-HBA"/>
<outlet property="delegate" destination="-2" id="c5n-ve-3Uw"/>
</connections>
</searchField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cp4-2G-8aG" userLabel="Site Answer">
<rect key="frame" x="189" y="12" width="221" height="29"/>
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<contentFilters>
<ciFilter name="CIGloom">
<configuration>
<null key="inputImage"/>
<real key="inputIntensity" value="0.80000000000000004"/>
<real key="inputRadius" value="8"/>
</configuration>
</ciFilter>
</contentFilters>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="fewc fom pugsuhe xav" placeholderString="" id="oYj-IR-xmw">
<font key="font" size="18" name="SourceCodePro-Regular"/>
<color key="textColor" name="keyboardFocusIndicatorColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="TxZ-TU-RMn">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.answer" id="Ba7-t3-euS"/>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ond-dT-x5d" userLabel="Site Password Tip">
<rect key="frame" x="220" y="138" width="160" height="14"/>
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Your password for apple.com:" id="CgJ-XZ-6Hy">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="Jvv-jZ-PG1">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="hidden2" keyPath="selection.content.length" previousBinding="Jvv-jZ-PG1" id="OXN-Zm-1ra">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
@ -262,11 +311,6 @@
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="Jvv-jZ-PG1">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ia6-7b-dFr">
@ -275,7 +319,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="No password set. Click &quot;Change Password&quot; on the bottom to set one." id="eDQ-iz-97a">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -312,7 +355,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Master Password generates passwords for your sites (and other things)." id="YyD-hd-wi3">
<font key="font" size="16" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -341,7 +383,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" id="9c4-NI-NM0">
<font key="font" size="12" name="HelveticaNeue"/>
<string key="title">— When you create a new account, use the password Master Password gives you for it.
@ -373,16 +414,19 @@
<constraints>
<constraint firstAttribute="centerY" secondItem="XUV-zU-Y9c" secondAttribute="centerY" id="6Qf-5O-Cvk"/>
<constraint firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="7sl-qi-HY9"/>
<constraint firstItem="cp4-2G-8aG" firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="Dx0-IB-hUM"/>
<constraint firstItem="Ia6-7b-dFr" firstAttribute="centerY" secondItem="XUV-zU-Y9c" secondAttribute="centerY" id="KqM-uR-Obm"/>
<constraint firstItem="Ia6-7b-dFr" firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="NFQ-aw-8tm"/>
<constraint firstAttribute="centerX" secondItem="sYt-eL-uwt" secondAttribute="centerX" id="OFw-vb-I71"/>
<constraint firstItem="XUV-zU-Y9c" firstAttribute="top" secondItem="Ond-dT-x5d" secondAttribute="bottom" constant="8" symbolic="YES" id="UgV-J6-B5T"/>
<constraint firstItem="cp4-2G-8aG" firstAttribute="top" secondItem="XUV-zU-Y9c" secondAttribute="bottom" id="T6W-P9-0vj"/>
<constraint firstItem="XUV-zU-Y9c" firstAttribute="top" secondItem="Ond-dT-x5d" secondAttribute="bottom" id="UgV-J6-B5T"/>
<constraint firstItem="Ond-dT-x5d" firstAttribute="centerX" secondItem="XUV-zU-Y9c" secondAttribute="centerX" id="UhT-LQ-aZ8"/>
<constraint firstItem="eBx-2g-chS" firstAttribute="centerX" secondItem="cp4-2G-8aG" secondAttribute="centerX" id="cHz-Q1-8ii"/>
<constraint firstItem="sYt-eL-uwt" firstAttribute="top" secondItem="OaQ-of-zmb" secondAttribute="bottom" constant="8" symbolic="YES" id="hjJ-f1-mFv"/>
<constraint firstItem="cp4-2G-8aG" firstAttribute="top" secondItem="eBx-2g-chS" secondAttribute="bottom" constant="-8" id="inf-AC-ger"/>
<constraint firstItem="sYt-eL-uwt" firstAttribute="centerX" secondItem="OaQ-of-zmb" secondAttribute="centerX" id="mu2-se-Mtn"/>
<constraint firstAttribute="centerY" secondItem="sYt-eL-uwt" secondAttribute="centerY" id="zLS-QG-MKS"/>
</constraints>
<animations/>
</customView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="OnR-s6-d4P" userLabel="Site Name Label">
<rect key="frame" x="209" y="310" width="223" height="20"/>
@ -390,7 +434,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" red="0.0" green="0.0" blue="0.0" alpha="0.80000000000000004" colorSpace="calibratedRGB"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Maarten Billemont's password for:" id="1Lb-d0-fQD">
<font key="font" size="14" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -406,7 +449,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" red="0.0" green="0.0" blue="0.0" alpha="0.80000000000000004" colorSpace="calibratedRGB"/>
</shadow>
<animations/>
<searchFieldCell key="cell" selectable="YES" editable="YES" focusRingType="none" alignment="center" placeholderString="Site Name" sendsSearchStringImmediately="YES" id="ppl-2c-1E9">
<font key="font" size="36" name="HelveticaNeue-Thin"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -424,7 +466,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.69999999999999996" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Type the name of your site (eg. apple.com), then hit enter ⏎ to create a password for it." id="QTI-cz-Onx">
<font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -443,14 +484,15 @@
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rhm-sC-xFS" userLabel="Site Name Tip">
<rect key="frame" x="37" y="235" width="566" height="15"/>
<rect key="frame" x="150" y="220" width="340" height="30"/>
<shadow key="shadow" blurRadius="0.5">
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.80000000000000004" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="Hit enter ⏎ to copy the password, then paste it using ⌘V. Use the arrows ⇅ to navigate the list or esc ⎋ to exit." id="n3W-XU-dya">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="n3W-XU-dya">
<font key="font" size="11" name="HelveticaNeue"/>
<string key="title">Hit enter ⏎ to copy the password, hold shift ⇧ to copy the answer.
Use the arrows ⇅ to navigate the list or esc ⎋ to exit.</string>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
@ -468,15 +510,14 @@
</connections>
</textField>
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="35" horizontalPageScroll="10" verticalLineScroll="35" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="Bme-XK-MMc" userLabel="Sites Table">
<rect key="frame" x="64" y="80" width="512" height="147"/>
<rect key="frame" x="64" y="80" width="512" height="132"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="e11-59-xSS">
<rect key="frame" x="0.0" y="0.0" width="512" height="147"/>
<rect key="frame" x="0.0" y="0.0" width="512" height="132"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="33" rowSizeStyle="automatic" viewBased="YES" floatsGroupRows="NO" id="xvJ-5c-vDp" customClass="MPSitesTableView">
<rect key="frame" x="0.0" y="0.0" width="515" height="0.0"/>
<rect key="frame" x="0.0" y="0.0" width="515" height="132"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" white="1" alpha="0.0" colorSpace="deviceWhite"/>
<color key="gridColor" name="selectedControlColor" catalog="System" colorSpace="catalog"/>
@ -504,7 +545,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="0.80000000000000004" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" alignment="center" title="apple.com" id="o0g-Zv-pH4">
<font key="font" size="24" name="HelveticaNeue-Thin"/>
<color key="textColor" name="alternateSelectedControlTextColor" catalog="System" colorSpace="catalog"/>
@ -533,7 +573,6 @@
</configuration>
</ciFilter>
</backgroundFilters>
<animations/>
<connections>
<outlet property="textField" destination="ydd-Rv-tra" id="lMV-D4-Ilq"/>
</connections>
@ -549,21 +588,17 @@
</connections>
</tableView>
</subviews>
<animations/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="calibratedRGB"/>
</clipView>
<constraints>
<constraint firstAttribute="width" constant="512" id="qfu-pO-SvM"/>
</constraints>
<animations/>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="8wr-pu-1lc">
<rect key="frame" x="-100" y="-100" width="512" height="15"/>
<autoresizingMask key="autoresizingMask"/>
<animations/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="mcf-ST-XXI">
<autoresizingMask key="autoresizingMask"/>
<animations/>
</scroller>
<connections>
<binding destination="-2" name="hidden" keyPath="locked" id="FF1-c9-zmm"/>
@ -571,7 +606,6 @@
</scrollView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="brI-fg-Kav">
<rect key="frame" x="260" y="45" width="122" height="19"/>
<animations/>
<buttonCell key="cell" type="recessed" title="Change Password" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="FQu-fM-NWY" customClass="MPNoStateButtonCell">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
@ -602,7 +636,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘P" id="MyN-x6-dMk">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -640,7 +673,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Click to set a password:" id="gjc-Fw-xa1">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -678,7 +710,6 @@
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vES-W5-m4x">
<rect key="frame" x="243" y="19" width="155" height="19"/>
<animations/>
<buttonCell key="cell" type="recessed" title="Change Password Type" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Fom-sN-EtZ" customClass="MPNoStateButtonCell">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
@ -700,7 +731,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘T" id="HFM-Bk-akx">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -725,7 +755,6 @@
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XuF-Sp-6JD">
<rect key="frame" x="406" y="19" width="80" height="19"/>
<animations/>
<buttonCell key="cell" type="recessed" title="Delete Site" bezelStyle="recessed" alignment="center" refusesFirstResponder="YES" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="26m-of-YMQ" customClass="MPNoStateButtonCell">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
@ -747,7 +776,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘D" id="PPC-be-w4E">
<font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -772,7 +800,6 @@
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1Qo-iG-CQt">
<rect key="frame" x="126" y="19" width="109" height="19"/>
<animations/>
<buttonCell key="cell" type="recessed" title="Set Login Name" bezelStyle="recessed" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="QFo-9y-aVe" customClass="MPNoStateButtonCell">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
<font key="font" metaFont="systemBold" size="12"/>
@ -799,7 +826,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="⌘L" id="fUB-rF-7x8">
<font key="font" size="11" name="HelveticaNeue"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -828,7 +854,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Upgrade your site's algorithm version for maximum protection:" id="3ds-qG-YNd">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -856,7 +881,6 @@
<subviews>
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mcq-qD-yte">
<rect key="frame" x="-3" y="-3" width="19" height="27"/>
<animations/>
<stepperCell key="cell" continuous="YES" alignment="left" minValue="1" maxValue="1000" doubleValue="1" id="73y-03-zHt"/>
<connections>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.algorithmVersion" id="GyA-hK-6cD"/>
@ -868,7 +892,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="V1" id="Pjy-Fm-zwB">
<font key="font" size="12" name="HelveticaNeue-Medium"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -879,7 +902,6 @@
</connections>
</textField>
</subviews>
<animations/>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
@ -901,7 +923,6 @@
<subviews>
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="XgA-Vl-CKh" userLabel="Counter Stepper">
<rect key="frame" x="-3" y="-3" width="19" height="27"/>
<animations/>
<stepperCell key="cell" continuous="YES" alignment="left" minValue="1" maxValue="1000" doubleValue="1" id="ikF-n4-xiI"/>
<connections>
<binding destination="mcS-ik-b0n" name="value" keyPath="selection.counter" id="qmm-6z-boy"/>
@ -913,7 +934,6 @@
<size key="offset" width="0.0" height="1"/>
<color key="color" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</shadow>
<animations/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="1" id="dhQ-bJ-rn3">
<font key="font" size="12" name="HelveticaNeue-Medium"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@ -924,7 +944,6 @@
</connections>
</textField>
</subviews>
<animations/>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
@ -934,6 +953,11 @@
<real value="3.4028234663852886e+38"/>
</customSpacing>
<connections>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="9vk-TH-Bm2">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="hidden2" keyPath="selection.generated" previousBinding="9vk-TH-Bm2" id="B6u-H8-b9o">
<dictionary key="options">
<integer key="NSMultipleValuesPlaceholder" value="-1"/>
@ -943,11 +967,6 @@
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="9vk-TH-Bm2">
<dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string>
</dictionary>
</binding>
</connections>
</stackView>
</subviews>
@ -1014,7 +1033,6 @@
<constraint firstItem="gAU-xs-aae" firstAttribute="centerX" secondItem="Aue-Zx-6Mf" secondAttribute="centerX" id="yxU-bl-dmQ"/>
<constraint firstItem="npC-Kk-gUM" firstAttribute="top" secondItem="CnS-iI-dhr" secondAttribute="bottom" constant="8" symbolic="YES" id="zs0-eA-5MW"/>
</constraints>
<animations/>
</view>
<point key="canvasLocation" x="-267" y="279"/>
</window>
@ -1024,16 +1042,15 @@
<binding destination="-2" name="contentArray" keyPath="sites" id="c96-Dv-HK1"/>
</connections>
</arrayController>
<box autoresizesSubviews="NO" misplaced="YES" title="Password Types" borderType="line" titlePosition="noTitle" id="bZe-7q-i6q">
<box autoresizesSubviews="NO" title="Password Types" borderType="line" titlePosition="noTitle" id="bZe-7q-i6q">
<rect key="frame" x="0.0" y="0.0" width="416" height="250"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<view key="contentView" id="hAc-y9-IMT">
<rect key="frame" x="1" y="1" width="414" height="248"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<matrix verticalHuggingPriority="750" misplaced="YES" allowsEmptySelection="NO" autorecalculatesCellSize="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3fr-Fd-pxx">
<matrix verticalHuggingPriority="750" allowsEmptySelection="NO" autorecalculatesCellSize="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3fr-Fd-pxx">
<rect key="frame" x="18" y="78" width="378" height="158"/>
<animations/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<size key="cellSize" width="179" height="18"/>
<size key="intercellSpacing" width="4" height="2"/>
@ -1078,9 +1095,8 @@
</column>
</cells>
</matrix>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kCO-1M-Wz1">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kCO-1M-Wz1">
<rect key="frame" x="16" y="14" width="382" height="56"/>
<animations/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="kl0-P1-6ZY">
<font key="font" metaFont="toolTip"/>
<string key="title">"Personal password" allows you to store your own password. It cannot be regenerated in the event of loss. "Device private password" is similar but will never leave your device: it cannot be synced, backed up or exported.</string>
@ -1089,7 +1105,6 @@
</textFieldCell>
</textField>
</subviews>
<animations/>
</view>
<constraints>
<constraint firstItem="kCO-1M-Wz1" firstAttribute="top" secondItem="3fr-Fd-pxx" secondAttribute="bottom" constant="8" symbolic="YES" id="GSx-ci-oqR"/>
@ -1100,13 +1115,12 @@
<constraint firstItem="3fr-Fd-pxx" firstAttribute="leading" secondItem="bZe-7q-i6q" secondAttribute="leading" constant="16" id="w0i-lL-lPE"/>
<constraint firstItem="kCO-1M-Wz1" firstAttribute="leading" secondItem="bZe-7q-i6q" secondAttribute="leading" constant="16" id="wBb-UE-BfN"/>
</constraints>
<animations/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="message" size="11"/>
</box>
</objects>
<resources>
<image name="icon_gear" width="32" height="32"/>
<image name="small-screen" width="25" height="15.5"/>
</resources>
</document>

View File

@ -31,6 +31,8 @@
@property (nonatomic) NSString *typeName;
@property (nonatomic) NSString *content;
@property (nonatomic) NSString *displayedContent;
@property (nonatomic) NSString *question;
@property (nonatomic) NSString *answer;
@property (nonatomic) NSString *loginName;
@property (nonatomic) NSNumber *uses;
@property (nonatomic) NSUInteger counter;

View File

@ -194,13 +194,18 @@
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[self updateContent:[MPSiteEntity existingObjectWithID:_entityOID inContext:context]];
}];
else
PearlNotMainQueue( ^{
NSString *password = [self.algorithm generatePasswordForSiteNamed:self.name ofType:self.type withCounter:self.counter
usingKey:[MPAppDelegate_Shared get].key];
NSString *loginName = [self.algorithm generateLoginForSiteNamed:self.name usingKey:[MPAppDelegate_Shared get].key];
[self updatePasswordWithResult:password];
[self updateLoginNameWithResult:loginName];
[self updatePasswordWithResult:
[self.algorithm generatePasswordForSiteNamed:self.name ofType:self.type withCounter:self.counter
usingKey:[MPAppDelegate_Shared get].key]];
[self updateLoginNameWithResult:
[self.algorithm generateLoginForSiteNamed:self.name
usingKey:[MPAppDelegate_Shared get].key]];
[self updateAnswerWithResult:
[self.algorithm generateAnswerForSiteNamed:self.name onQuestion:self.question
usingKey:[MPAppDelegate_Shared get].key]];
} );
}
@ -212,6 +217,9 @@
[entity resolveLoginUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
[self updateLoginNameWithResult:result];
}];
[entity resolveSiteAnswerUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
[self updateAnswerWithResult:result];
}];
}
- (void)updatePasswordWithResult:(NSString *)result {
@ -239,4 +247,11 @@
} );
}
- (void)updateAnswerWithResult:(NSString *)answer {
PearlMainQueue( ^{
self.answer = answer;
} );
}
@end

View File

@ -178,7 +178,7 @@
else if ([cell isKindOfClass:[MPSendAnswersCell class]]) {
NSString *body;
if (!_multiple) {
NSObject *answer = [site.algorithm resolveAnswerForSite:site usingKey:[MPiOSAppDelegate get].key];
NSObject *answer = [site resolveSiteAnswerUsingKey:[MPiOSAppDelegate get].key];
body = strf( @"Master Password generated the following security answer for your site: %@\n\n"
@"%@\n"
@"\n\nYou should use this as the answer to each security question the site asks you.\n"
@ -188,7 +188,7 @@
NSMutableString *bodyBuilder = [NSMutableString string];
[bodyBuilder appendFormat:@"Master Password generated the following security answers for your site: %@\n\n", site.name];
for (MPSiteQuestionEntity *question in site.questions) {
NSObject *answer = [site.algorithm resolveAnswerForQuestion:question usingKey:[MPiOSAppDelegate get].key];
NSObject *answer = [question resolveQuestionAnswerUsingKey:[MPiOSAppDelegate get].key];
[bodyBuilder appendFormat:@"For question: '%@', use answer: %@\n", question.keyword, answer];
}
[bodyBuilder appendFormat:@"\n\nUse the answer for the matching security question.\n"
@ -241,7 +241,7 @@
self.titleLabel.text = strl( @"Answer for %@:", site.name );
self.answerField.text = @"...";
[site.algorithm resolveAnswerForSite:site usingKey:[MPiOSAppDelegate get].key result:^(NSString *result) {
[site resolveSiteAnswerUsingKey:[MPiOSAppDelegate get].key result:^(NSString *result) {
PearlMainQueue( ^{
self.answerField.text = result;
} );
@ -330,7 +330,7 @@
PearlMainQueue( ^{
self.answerField.text = @"...";
} );
[site.algorithm resolveAnswerForQuestion:question usingKey:[MPiOSAppDelegate get].key result:^(NSString *result) {
[question resolveQuestionAnswerUsingKey:[MPiOSAppDelegate get].key result:^(NSString *result) {
PearlMainQueue( ^{
self.questionField.text = keyword;
self.answerField.text = result;