Initial working password application with types and history.
5
.idea/encodings.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||
</project>
|
||||
|
9
.idea/projectCodeStyle.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CodeStyleSettingsManager">
|
||||
<option name="PER_PROJECT_SETTINGS">
|
||||
<value />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
2
External/Pearl
vendored
@ -1 +1 @@
|
||||
Subproject commit de35f576ee290551f282c036f43313b15b2b6594
|
||||
Subproject commit 3cca78c6ebc874ef3168e674dbb7391f9a6dec52
|
@ -7,6 +7,15 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
DA007F5214B24DCD00251337 /* OPConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = DA007F5114B24DCD00251337 /* OPConfig.m */; };
|
||||
DA007F5514B25EE100251337 /* ciphers.plist in Resources */ = {isa = PBXBuildFile; fileRef = DA007F5414B25EE100251337 /* ciphers.plist */; };
|
||||
DA007F5614B26EFA00251337 /* Pearl.strings in Resources */ = {isa = PBXBuildFile; fileRef = DAC77CD41482AAD600BCF976 /* Pearl.strings */; };
|
||||
DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */; };
|
||||
DA34DA0D14B1BC7D00F721C1 /* OPElementStoredEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA34DA0C14B1BC7D00F721C1 /* OPElementStoredEntity.m */; };
|
||||
DA34DA1114B1BC7E00F721C1 /* OPElementEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA34DA1014B1BC7E00F721C1 /* OPElementEntity.m */; };
|
||||
DA34DA1614B1BEA100F721C1 /* OPTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = DA34DA1514B1BEA100F721C1 /* OPTypes.m */; };
|
||||
DA55B29E14B38272001131B7 /* OPContentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DA55B29D14B38272001131B7 /* OPContentViewController.m */; };
|
||||
DA55B2A214B4EB47001131B7 /* OPSearchDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DA55B2A114B4EB46001131B7 /* OPSearchDelegate.m */; };
|
||||
DA5BFA49147E415C00F98B1E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA48147E415C00F98B1E /* UIKit.framework */; };
|
||||
DA5BFA4B147E415C00F98B1E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
|
||||
DA5BFA4D147E415C00F98B1E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4C147E415C00F98B1E /* CoreGraphics.framework */; };
|
||||
@ -18,7 +27,37 @@
|
||||
DA5BFA61147E415C00F98B1E /* MainStoryboard_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DA5BFA5F147E415C00F98B1E /* MainStoryboard_iPad.storyboard */; };
|
||||
DA5BFA64147E415C00F98B1E /* OnePassword.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DA5BFA62147E415C00F98B1E /* OnePassword.xcdatamodeld */; };
|
||||
DA5BFA67147E415C00F98B1E /* OPMainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5BFA66147E415C00F98B1E /* OPMainViewController.m */; };
|
||||
DAC63257148679600075AEA5 /* OPSaltedCipherViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC63256148679600075AEA5 /* OPSaltedCipherViewController.m */; };
|
||||
DA7C28C414AF078900491972 /* Bold_Lines.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28A514AF078900491972 /* Bold_Lines.png */; };
|
||||
DA7C28C514AF078900491972 /* Box.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28A614AF078900491972 /* Box.png */; };
|
||||
DA7C28C614AF078900491972 /* Dashed_Divider.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28A714AF078900491972 /* Dashed_Divider.png */; };
|
||||
DA7C28C714AF078900491972 /* Dashed_Divider_.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28A814AF078900491972 /* Dashed_Divider_.png */; };
|
||||
DA7C28C814AF078900491972 /* Dashed_Divider_Highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28A914AF078900491972 /* Dashed_Divider_Highlight.png */; };
|
||||
DA7C28C914AF078900491972 /* Dotted_Dividers.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28AA14AF078900491972 /* Dotted_Dividers.png */; };
|
||||
DA7C28CA14AF078900491972 /* Doubble_Shadow_.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28AB14AF078900491972 /* Doubble_Shadow_.png */; };
|
||||
DA7C28CB14AF078900491972 /* Double.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28AC14AF078900491972 /* Double.png */; };
|
||||
DA7C28CC14AF078900491972 /* Double_Page.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28AD14AF078900491972 /* Double_Page.png */; };
|
||||
DA7C28CD14AF078900491972 /* Double_Page_2.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28AE14AF078900491972 /* Double_Page_2.png */; };
|
||||
DA7C28CE14AF078900491972 /* Double_Shadow.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28AF14AF078900491972 /* Double_Shadow.png */; };
|
||||
DA7C28CF14AF078900491972 /* Double_With_White.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28B014AF078900491972 /* Double_With_White.png */; };
|
||||
DA7C28D014AF078900491972 /* Double_With_White_Strong.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28B114AF078900491972 /* Double_With_White_Strong.png */; };
|
||||
DA7C28D114AF078900491972 /* Help.rtf in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28B214AF078900491972 /* Help.rtf */; };
|
||||
DA7C28D214AF078900491972 /* Highlight_Smooth_Divider.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28B314AF078900491972 /* Highlight_Smooth_Divider.png */; };
|
||||
DA7C28D314AF078900491972 /* Highlight_Smooth_Divider_copy.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28B414AF078900491972 /* Highlight_Smooth_Divider_copy.png */; };
|
||||
DA7C28D414AF078900491972 /* Highlight_StrongDivider_copy_3.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28B514AF078900491972 /* Highlight_StrongDivider_copy_3.png */; };
|
||||
DA7C28D514AF078900491972 /* Page.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28B614AF078900491972 /* Page.png */; };
|
||||
DA7C28D614AF078900491972 /* Rectangular.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28B714AF078900491972 /* Rectangular.png */; };
|
||||
DA7C28D714AF078900491972 /* Rounded.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28B814AF078900491972 /* Rounded.png */; };
|
||||
DA7C28D814AF078900491972 /* Rounded_Inverted.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28B914AF078900491972 /* Rounded_Inverted.png */; };
|
||||
DA7C28D914AF078900491972 /* Simple.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28BA14AF078900491972 /* Simple.png */; };
|
||||
DA7C28DA14AF078900491972 /* Simple_Divider.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28BB14AF078900491972 /* Simple_Divider.png */; };
|
||||
DA7C28DB14AF078900491972 /* Simple_Divider_.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28BC14AF078900491972 /* Simple_Divider_.png */; };
|
||||
DA7C28DC14AF078900491972 /* Simple_Divider__Strong.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28BD14AF078900491972 /* Simple_Divider__Strong.png */; };
|
||||
DA7C28DD14AF078900491972 /* Simple_Divider_Strong.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28BE14AF078900491972 /* Simple_Divider_Strong.png */; };
|
||||
DA7C28DE14AF078900491972 /* Single_Shadow.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28BF14AF078900491972 /* Single_Shadow.png */; };
|
||||
DA7C28DF14AF078900491972 /* Single_Shadow_.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28C014AF078900491972 /* Single_Shadow_.png */; };
|
||||
DA7C28E014AF078900491972 /* Smooth_Divider.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28C114AF078900491972 /* Smooth_Divider.png */; };
|
||||
DA7C28E114AF078900491972 /* Square.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28C214AF078900491972 /* Square.png */; };
|
||||
DA7C28E214AF078900491972 /* White_Rectangular.png in Resources */ = {isa = PBXBuildFile; fileRef = DA7C28C314AF078900491972 /* White_Rectangular.png */; };
|
||||
DAC6325E1486805C0075AEA5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
|
||||
DAC6326D148680650075AEA5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
|
||||
DAC63277148680700075AEA5 /* libuicolor-utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAC6325D1486805C0075AEA5 /* libuicolor-utilities.a */; };
|
||||
@ -126,6 +165,20 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
DA007F5014B24DCC00251337 /* OPConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OPConfig.h; sourceTree = "<group>"; };
|
||||
DA007F5114B24DCD00251337 /* OPConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPConfig.m; sourceTree = "<group>"; };
|
||||
DA007F5414B25EE100251337 /* ciphers.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ciphers.plist; sourceTree = "<group>"; };
|
||||
DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
||||
DA34DA0B14B1BC7D00F721C1 /* OPElementStoredEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OPElementStoredEntity.h; sourceTree = "<group>"; };
|
||||
DA34DA0C14B1BC7D00F721C1 /* OPElementStoredEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPElementStoredEntity.m; sourceTree = "<group>"; };
|
||||
DA34DA0F14B1BC7E00F721C1 /* OPElementEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OPElementEntity.h; sourceTree = "<group>"; };
|
||||
DA34DA1014B1BC7E00F721C1 /* OPElementEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPElementEntity.m; sourceTree = "<group>"; };
|
||||
DA34DA1414B1BEA100F721C1 /* OPTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OPTypes.h; sourceTree = "<group>"; };
|
||||
DA34DA1514B1BEA100F721C1 /* OPTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPTypes.m; sourceTree = "<group>"; };
|
||||
DA55B29C14B38272001131B7 /* OPContentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OPContentViewController.h; sourceTree = "<group>"; };
|
||||
DA55B29D14B38272001131B7 /* OPContentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPContentViewController.m; sourceTree = "<group>"; };
|
||||
DA55B2A014B4EB46001131B7 /* OPSearchDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OPSearchDelegate.h; sourceTree = "<group>"; };
|
||||
DA55B2A114B4EB46001131B7 /* OPSearchDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPSearchDelegate.m; sourceTree = "<group>"; };
|
||||
DA5BFA44147E415C00F98B1E /* OnePassword.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OnePassword.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DA5BFA48147E415C00F98B1E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||
DA5BFA4A147E415C00F98B1E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
@ -142,8 +195,37 @@
|
||||
DA5BFA63147E415C00F98B1E /* OnePassword.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = OnePassword.xcdatamodel; sourceTree = "<group>"; };
|
||||
DA5BFA65147E415C00F98B1E /* OPMainViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OPMainViewController.h; sourceTree = "<group>"; };
|
||||
DA5BFA66147E415C00F98B1E /* OPMainViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OPMainViewController.m; sourceTree = "<group>"; };
|
||||
DAC63255148679600075AEA5 /* OPSaltedCipherViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OPSaltedCipherViewController.h; sourceTree = "<group>"; };
|
||||
DAC63256148679600075AEA5 /* OPSaltedCipherViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OPSaltedCipherViewController.m; sourceTree = "<group>"; };
|
||||
DA7C28A514AF078900491972 /* Bold_Lines.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Bold_Lines.png; sourceTree = "<group>"; };
|
||||
DA7C28A614AF078900491972 /* Box.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Box.png; sourceTree = "<group>"; };
|
||||
DA7C28A714AF078900491972 /* Dashed_Divider.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Dashed_Divider.png; sourceTree = "<group>"; };
|
||||
DA7C28A814AF078900491972 /* Dashed_Divider_.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Dashed_Divider_.png; sourceTree = "<group>"; };
|
||||
DA7C28A914AF078900491972 /* Dashed_Divider_Highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Dashed_Divider_Highlight.png; sourceTree = "<group>"; };
|
||||
DA7C28AA14AF078900491972 /* Dotted_Dividers.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Dotted_Dividers.png; sourceTree = "<group>"; };
|
||||
DA7C28AB14AF078900491972 /* Doubble_Shadow_.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Doubble_Shadow_.png; sourceTree = "<group>"; };
|
||||
DA7C28AC14AF078900491972 /* Double.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Double.png; sourceTree = "<group>"; };
|
||||
DA7C28AD14AF078900491972 /* Double_Page.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Double_Page.png; sourceTree = "<group>"; };
|
||||
DA7C28AE14AF078900491972 /* Double_Page_2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Double_Page_2.png; sourceTree = "<group>"; };
|
||||
DA7C28AF14AF078900491972 /* Double_Shadow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Double_Shadow.png; sourceTree = "<group>"; };
|
||||
DA7C28B014AF078900491972 /* Double_With_White.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Double_With_White.png; sourceTree = "<group>"; };
|
||||
DA7C28B114AF078900491972 /* Double_With_White_Strong.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Double_With_White_Strong.png; sourceTree = "<group>"; };
|
||||
DA7C28B214AF078900491972 /* Help.rtf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.rtf; path = Help.rtf; sourceTree = "<group>"; };
|
||||
DA7C28B314AF078900491972 /* Highlight_Smooth_Divider.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Highlight_Smooth_Divider.png; sourceTree = "<group>"; };
|
||||
DA7C28B414AF078900491972 /* Highlight_Smooth_Divider_copy.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Highlight_Smooth_Divider_copy.png; sourceTree = "<group>"; };
|
||||
DA7C28B514AF078900491972 /* Highlight_StrongDivider_copy_3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Highlight_StrongDivider_copy_3.png; sourceTree = "<group>"; };
|
||||
DA7C28B614AF078900491972 /* Page.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Page.png; sourceTree = "<group>"; };
|
||||
DA7C28B714AF078900491972 /* Rectangular.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Rectangular.png; sourceTree = "<group>"; };
|
||||
DA7C28B814AF078900491972 /* Rounded.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Rounded.png; sourceTree = "<group>"; };
|
||||
DA7C28B914AF078900491972 /* Rounded_Inverted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Rounded_Inverted.png; sourceTree = "<group>"; };
|
||||
DA7C28BA14AF078900491972 /* Simple.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Simple.png; sourceTree = "<group>"; };
|
||||
DA7C28BB14AF078900491972 /* Simple_Divider.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Simple_Divider.png; sourceTree = "<group>"; };
|
||||
DA7C28BC14AF078900491972 /* Simple_Divider_.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Simple_Divider_.png; sourceTree = "<group>"; };
|
||||
DA7C28BD14AF078900491972 /* Simple_Divider__Strong.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Simple_Divider__Strong.png; sourceTree = "<group>"; };
|
||||
DA7C28BE14AF078900491972 /* Simple_Divider_Strong.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Simple_Divider_Strong.png; sourceTree = "<group>"; };
|
||||
DA7C28BF14AF078900491972 /* Single_Shadow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Single_Shadow.png; sourceTree = "<group>"; };
|
||||
DA7C28C014AF078900491972 /* Single_Shadow_.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Single_Shadow_.png; sourceTree = "<group>"; };
|
||||
DA7C28C114AF078900491972 /* Smooth_Divider.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Smooth_Divider.png; sourceTree = "<group>"; };
|
||||
DA7C28C214AF078900491972 /* Square.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Square.png; sourceTree = "<group>"; };
|
||||
DA7C28C314AF078900491972 /* White_Rectangular.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = White_Rectangular.png; sourceTree = "<group>"; };
|
||||
DAC6325D1486805C0075AEA5 /* libuicolor-utilities.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libuicolor-utilities.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DAC6326C148680650075AEA5 /* libjrswizzle.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libjrswizzle.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DAC632791486809A0075AEA5 /* JRSwizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JRSwizzle.h; path = External/Pearl/External/jrswizzle/JRSwizzle.h; sourceTree = SOURCE_ROOT; };
|
||||
@ -1235,6 +1317,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DA04E33E14B1E70400ECA4F3 /* MobileCoreServices.framework in Frameworks */,
|
||||
DAC632891486D9690075AEA5 /* Security.framework in Frameworks */,
|
||||
DAC77CB91482929100BCF976 /* libPearl.a in Frameworks */,
|
||||
DA5BFA49147E415C00F98B1E /* UIKit.framework in Frameworks */,
|
||||
@ -1276,6 +1359,7 @@
|
||||
DA5BFA39147E415C00F98B1E = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA04E33D14B1E70400ECA4F3 /* MobileCoreServices.framework */,
|
||||
DAC632871486D95D0075AEA5 /* Security.framework */,
|
||||
DA5BFA50147E415C00F98B1E /* OnePassword */,
|
||||
DAC77CAF148291A600BCF976 /* Pearl */,
|
||||
@ -1311,20 +1395,25 @@
|
||||
DA5BFA50147E415C00F98B1E /* OnePassword */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA7C28A214AF02A000491972 /* Models */,
|
||||
DA7C28A314AF02B100491972 /* Data */,
|
||||
DA5BFA59147E415C00F98B1E /* OPAppDelegate.h */,
|
||||
DA5BFA5A147E415C00F98B1E /* OPAppDelegate.m */,
|
||||
DA5BFA5C147E415C00F98B1E /* MainStoryboard_iPhone.storyboard */,
|
||||
DA5BFA5F147E415C00F98B1E /* MainStoryboard_iPad.storyboard */,
|
||||
DA5BFA65147E415C00F98B1E /* OPMainViewController.h */,
|
||||
DA5BFA66147E415C00F98B1E /* OPMainViewController.m */,
|
||||
DA55B2A014B4EB46001131B7 /* OPSearchDelegate.h */,
|
||||
DA55B2A114B4EB46001131B7 /* OPSearchDelegate.m */,
|
||||
DAC781341482E67300BCF976 /* OPRecentViewController.h */,
|
||||
DAC781351482E67300BCF976 /* OPRecentViewController.m */,
|
||||
DAE2C645148247E500BA6B10 /* OPTypeViewController.h */,
|
||||
DAE2C646148247E500BA6B10 /* OPTypeViewController.m */,
|
||||
DAC63255148679600075AEA5 /* OPSaltedCipherViewController.h */,
|
||||
DAC63256148679600075AEA5 /* OPSaltedCipherViewController.m */,
|
||||
DA5BFA62147E415C00F98B1E /* OnePassword.xcdatamodeld */,
|
||||
DA55B29C14B38272001131B7 /* OPContentViewController.h */,
|
||||
DA55B29D14B38272001131B7 /* OPContentViewController.m */,
|
||||
DA5BFA51147E415C00F98B1E /* Supporting Files */,
|
||||
DA34DA1414B1BEA100F721C1 /* OPTypes.h */,
|
||||
DA34DA1514B1BEA100F721C1 /* OPTypes.m */,
|
||||
DA007F5014B24DCC00251337 /* OPConfig.h */,
|
||||
DA007F5114B24DCD00251337 /* OPConfig.m */,
|
||||
);
|
||||
path = OnePassword;
|
||||
sourceTree = "<group>";
|
||||
@ -1332,14 +1421,75 @@
|
||||
DA5BFA51147E415C00F98B1E /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA7C28A414AF078900491972 /* divider */,
|
||||
DA5BFA52147E415C00F98B1E /* OnePassword-Info.plist */,
|
||||
DA5BFA53147E415C00F98B1E /* InfoPlist.strings */,
|
||||
DA5BFA56147E415C00F98B1E /* main.m */,
|
||||
DA5BFA58147E415C00F98B1E /* OnePassword-Prefix.pch */,
|
||||
DA007F5414B25EE100251337 /* ciphers.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DA7C28A214AF02A000491972 /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA5BFA5C147E415C00F98B1E /* MainStoryboard_iPhone.storyboard */,
|
||||
DA5BFA5F147E415C00F98B1E /* MainStoryboard_iPad.storyboard */,
|
||||
DA5BFA62147E415C00F98B1E /* OnePassword.xcdatamodeld */,
|
||||
);
|
||||
name = Models;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DA7C28A314AF02B100491972 /* Data */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA34DA0F14B1BC7E00F721C1 /* OPElementEntity.h */,
|
||||
DA34DA1014B1BC7E00F721C1 /* OPElementEntity.m */,
|
||||
DA34DA0B14B1BC7D00F721C1 /* OPElementStoredEntity.h */,
|
||||
DA34DA0C14B1BC7D00F721C1 /* OPElementStoredEntity.m */,
|
||||
);
|
||||
name = Data;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DA7C28A414AF078900491972 /* divider */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DA7C28A514AF078900491972 /* Bold_Lines.png */,
|
||||
DA7C28A614AF078900491972 /* Box.png */,
|
||||
DA7C28A714AF078900491972 /* Dashed_Divider.png */,
|
||||
DA7C28A814AF078900491972 /* Dashed_Divider_.png */,
|
||||
DA7C28A914AF078900491972 /* Dashed_Divider_Highlight.png */,
|
||||
DA7C28AA14AF078900491972 /* Dotted_Dividers.png */,
|
||||
DA7C28AB14AF078900491972 /* Doubble_Shadow_.png */,
|
||||
DA7C28AC14AF078900491972 /* Double.png */,
|
||||
DA7C28AD14AF078900491972 /* Double_Page.png */,
|
||||
DA7C28AE14AF078900491972 /* Double_Page_2.png */,
|
||||
DA7C28AF14AF078900491972 /* Double_Shadow.png */,
|
||||
DA7C28B014AF078900491972 /* Double_With_White.png */,
|
||||
DA7C28B114AF078900491972 /* Double_With_White_Strong.png */,
|
||||
DA7C28B214AF078900491972 /* Help.rtf */,
|
||||
DA7C28B314AF078900491972 /* Highlight_Smooth_Divider.png */,
|
||||
DA7C28B414AF078900491972 /* Highlight_Smooth_Divider_copy.png */,
|
||||
DA7C28B514AF078900491972 /* Highlight_StrongDivider_copy_3.png */,
|
||||
DA7C28B614AF078900491972 /* Page.png */,
|
||||
DA7C28B714AF078900491972 /* Rectangular.png */,
|
||||
DA7C28B814AF078900491972 /* Rounded.png */,
|
||||
DA7C28B914AF078900491972 /* Rounded_Inverted.png */,
|
||||
DA7C28BA14AF078900491972 /* Simple.png */,
|
||||
DA7C28BB14AF078900491972 /* Simple_Divider.png */,
|
||||
DA7C28BC14AF078900491972 /* Simple_Divider_.png */,
|
||||
DA7C28BD14AF078900491972 /* Simple_Divider__Strong.png */,
|
||||
DA7C28BE14AF078900491972 /* Simple_Divider_Strong.png */,
|
||||
DA7C28BF14AF078900491972 /* Single_Shadow.png */,
|
||||
DA7C28C014AF078900491972 /* Single_Shadow_.png */,
|
||||
DA7C28C114AF078900491972 /* Smooth_Divider.png */,
|
||||
DA7C28C214AF078900491972 /* Square.png */,
|
||||
DA7C28C314AF078900491972 /* White_Rectangular.png */,
|
||||
);
|
||||
path = divider;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DAC6325F1486805C0075AEA5 /* uicolor-utilities */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2678,6 +2828,39 @@
|
||||
DA5BFA55147E415C00F98B1E /* InfoPlist.strings in Resources */,
|
||||
DA5BFA5E147E415C00F98B1E /* MainStoryboard_iPhone.storyboard in Resources */,
|
||||
DA5BFA61147E415C00F98B1E /* MainStoryboard_iPad.storyboard in Resources */,
|
||||
DA7C28C414AF078900491972 /* Bold_Lines.png in Resources */,
|
||||
DA7C28C514AF078900491972 /* Box.png in Resources */,
|
||||
DA7C28C614AF078900491972 /* Dashed_Divider.png in Resources */,
|
||||
DA7C28C714AF078900491972 /* Dashed_Divider_.png in Resources */,
|
||||
DA7C28C814AF078900491972 /* Dashed_Divider_Highlight.png in Resources */,
|
||||
DA7C28C914AF078900491972 /* Dotted_Dividers.png in Resources */,
|
||||
DA7C28CA14AF078900491972 /* Doubble_Shadow_.png in Resources */,
|
||||
DA7C28CB14AF078900491972 /* Double.png in Resources */,
|
||||
DA7C28CC14AF078900491972 /* Double_Page.png in Resources */,
|
||||
DA7C28CD14AF078900491972 /* Double_Page_2.png in Resources */,
|
||||
DA7C28CE14AF078900491972 /* Double_Shadow.png in Resources */,
|
||||
DA7C28CF14AF078900491972 /* Double_With_White.png in Resources */,
|
||||
DA7C28D014AF078900491972 /* Double_With_White_Strong.png in Resources */,
|
||||
DA7C28D114AF078900491972 /* Help.rtf in Resources */,
|
||||
DA7C28D214AF078900491972 /* Highlight_Smooth_Divider.png in Resources */,
|
||||
DA7C28D314AF078900491972 /* Highlight_Smooth_Divider_copy.png in Resources */,
|
||||
DA7C28D414AF078900491972 /* Highlight_StrongDivider_copy_3.png in Resources */,
|
||||
DA7C28D514AF078900491972 /* Page.png in Resources */,
|
||||
DA7C28D614AF078900491972 /* Rectangular.png in Resources */,
|
||||
DA7C28D714AF078900491972 /* Rounded.png in Resources */,
|
||||
DA7C28D814AF078900491972 /* Rounded_Inverted.png in Resources */,
|
||||
DA7C28D914AF078900491972 /* Simple.png in Resources */,
|
||||
DA7C28DA14AF078900491972 /* Simple_Divider.png in Resources */,
|
||||
DA7C28DB14AF078900491972 /* Simple_Divider_.png in Resources */,
|
||||
DA7C28DC14AF078900491972 /* Simple_Divider__Strong.png in Resources */,
|
||||
DA7C28DD14AF078900491972 /* Simple_Divider_Strong.png in Resources */,
|
||||
DA7C28DE14AF078900491972 /* Single_Shadow.png in Resources */,
|
||||
DA7C28DF14AF078900491972 /* Single_Shadow_.png in Resources */,
|
||||
DA7C28E014AF078900491972 /* Smooth_Divider.png in Resources */,
|
||||
DA7C28E114AF078900491972 /* Square.png in Resources */,
|
||||
DA7C28E214AF078900491972 /* White_Rectangular.png in Resources */,
|
||||
DA007F5514B25EE100251337 /* ciphers.plist in Resources */,
|
||||
DA007F5614B26EFA00251337 /* Pearl.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -2694,7 +2877,12 @@
|
||||
DA5BFA67147E415C00F98B1E /* OPMainViewController.m in Sources */,
|
||||
DAE2C648148247E500BA6B10 /* OPTypeViewController.m in Sources */,
|
||||
DAC781361482E67300BCF976 /* OPRecentViewController.m in Sources */,
|
||||
DAC63257148679600075AEA5 /* OPSaltedCipherViewController.m in Sources */,
|
||||
DA34DA0D14B1BC7D00F721C1 /* OPElementStoredEntity.m in Sources */,
|
||||
DA34DA1114B1BC7E00F721C1 /* OPElementEntity.m in Sources */,
|
||||
DA34DA1614B1BEA100F721C1 /* OPTypes.m in Sources */,
|
||||
DA007F5214B24DCD00251337 /* OPConfig.m in Sources */,
|
||||
DA55B29E14B38272001131B7 /* OPContentViewController.m in Sources */,
|
||||
DA55B2A214B4EB47001131B7 /* OPSearchDelegate.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -2981,6 +3169,7 @@
|
||||
DAC632671486805C0075AEA5 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
DAC63274148680650075AEA5 /* Build configuration list for PBXNativeTarget "jrswizzle" */ = {
|
||||
isa = XCConfigurationList;
|
||||
@ -2989,6 +3178,7 @@
|
||||
DAC63276148680650075AEA5 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
DAC77CB7148291A600BCF976 /* Build configuration list for PBXNativeTarget "Pearl" */ = {
|
||||
isa = XCConfigurationList;
|
||||
|
@ -13,6 +13,9 @@
|
||||
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
|
||||
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
|
||||
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
|
||||
@property (strong, nonatomic) NSString *keyPhrase;
|
||||
|
||||
+ (OPAppDelegate *)get;
|
||||
|
||||
- (void)saveContext;
|
||||
- (NSURL *)applicationDocumentsDirectory;
|
||||
|
@ -15,9 +15,57 @@
|
||||
@synthesize managedObjectContext = __managedObjectContext;
|
||||
@synthesize managedObjectModel = __managedObjectModel;
|
||||
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
|
||||
@synthesize keyPhrase = _keyPhrase;
|
||||
|
||||
+ (void)initialize {
|
||||
|
||||
[Logger get].autoprintLevel = LogLevelDebug;
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NSString *keyPhraseHash = [OPConfig get].keyPhraseHash;
|
||||
|
||||
AlertViewController *keyPhraseAlert = [[AlertViewController alloc] initQuestionWithTitle:@"One Password"
|
||||
message:keyPhraseHash? @"Unlock with your master password:": @"Choose your master password:"
|
||||
tappedButtonBlock:
|
||||
^(NSInteger buttonIndex, NSString *answer) {
|
||||
if (buttonIndex == 0)
|
||||
exit(0);
|
||||
|
||||
if (![answer length]) {
|
||||
[AlertViewController showAlertWithTitle:[PearlStrings get].commonTitleError
|
||||
message:@"No master password entered."
|
||||
tappedButtonBlock:
|
||||
^(NSInteger buttonIndex) {
|
||||
exit(0);
|
||||
} cancelTitle:@"Quit" otherTitles:nil];
|
||||
}
|
||||
|
||||
NSString *answerHash = [[answer hashWith:PearlDigestSHA1] encodeHex];
|
||||
if (keyPhraseHash) {
|
||||
if (![keyPhraseHash isEqualToString:answerHash]) {
|
||||
[AlertViewController showAlertWithTitle:[PearlStrings get].commonTitleError
|
||||
message:@"Incorrect master password."
|
||||
tappedButtonBlock:
|
||||
^(NSInteger buttonIndex) {
|
||||
exit(0);
|
||||
} cancelTitle:@"Quit" otherTitles:nil];
|
||||
|
||||
return;
|
||||
}
|
||||
} else
|
||||
[OPConfig get].keyPhraseHash = answerHash;
|
||||
|
||||
self.keyPhrase = answer;
|
||||
} cancelTitle:@"Quit" otherTitles:@"Unlock", nil];
|
||||
keyPhraseAlert.alertField.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
keyPhraseAlert.alertField.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
keyPhraseAlert.alertField.secureTextEntry = YES;
|
||||
[keyPhraseAlert showAlert];
|
||||
});
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
// Override point for customization after application launch.
|
||||
return [super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
}
|
||||
@ -58,6 +106,11 @@
|
||||
[self saveContext];
|
||||
}
|
||||
|
||||
+ (OPAppDelegate *)get {
|
||||
|
||||
return (OPAppDelegate *)[super get];
|
||||
}
|
||||
|
||||
- (void)saveContext
|
||||
{
|
||||
NSError *error = nil;
|
||||
@ -106,6 +159,7 @@
|
||||
}
|
||||
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"OnePassword" withExtension:@"momd"];
|
||||
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
|
||||
|
||||
return __managedObjectModel;
|
||||
}
|
||||
|
||||
@ -124,7 +178,12 @@
|
||||
|
||||
NSError *error = nil;
|
||||
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
|
||||
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
|
||||
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL
|
||||
options:[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
(id)kCFBooleanTrue, NSMigratePersistentStoresAutomaticallyOption,
|
||||
(id)kCFBooleanTrue, NSInferMappingModelAutomaticallyOption,
|
||||
nil]
|
||||
error:&error])
|
||||
{
|
||||
/*
|
||||
Replace this implementation with code to handle the error appropriately.
|
||||
@ -149,8 +208,13 @@
|
||||
Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
|
||||
|
||||
*/
|
||||
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
|
||||
abort();
|
||||
err(@"Unresolved error %@, %@", error, [error userInfo]);
|
||||
#if DEBUG
|
||||
wrn(@"Deleted datastore: %@", storeURL);
|
||||
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
|
||||
#endif
|
||||
@throw [NSException exceptionWithName:error.domain reason:error.localizedDescription
|
||||
userInfo:[NSDictionary dictionaryWithObject:error forKey:@"cause"]];
|
||||
}
|
||||
|
||||
return __persistentStoreCoordinator;
|
||||
|
16
OnePassword/OPConfig.h
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// OPConfig.h
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 02/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
@interface OPConfig : Config
|
||||
|
||||
@property (nonatomic, retain) NSNumber *dataStoreError;
|
||||
@property (nonatomic, retain) NSString *keyPhraseHash;
|
||||
|
||||
+ (OPConfig *)get;
|
||||
|
||||
@end
|
34
OnePassword/OPConfig.m
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// OPConfig.m
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 02/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OPConfig.h"
|
||||
|
||||
@implementation OPConfig
|
||||
|
||||
@dynamic dataStoreError, keyPhraseHash;
|
||||
|
||||
|
||||
-(id) init {
|
||||
|
||||
if(!(self = [super init]))
|
||||
return self;
|
||||
|
||||
[self.defaults registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithBool:NO], NSStringFromSelector(@selector(dataStoreError)),
|
||||
|
||||
nil]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (OPConfig *)get {
|
||||
|
||||
return (OPConfig *)[super get];
|
||||
}
|
||||
|
||||
@end
|
16
OnePassword/OPContentViewController.h
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// OPContentViewController.h
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 03/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "OPElementEntity.h"
|
||||
|
||||
@interface OPContentViewController : UIViewController
|
||||
|
||||
@property (nonatomic, weak) OPElementEntity *activeElement;
|
||||
|
||||
@end
|
22
OnePassword/OPContentViewController.m
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// OPContentViewController.m
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 03/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OPContentViewController.h"
|
||||
|
||||
@implementation OPContentViewController
|
||||
@synthesize activeElement = _activeElement;
|
||||
|
||||
#pragma mark - View lifecycle
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
|
||||
|
||||
// Return YES for supported orientations
|
||||
return (interfaceOrientation == UIInterfaceOrientationPortrait);
|
||||
}
|
||||
|
||||
@end
|
26
OnePassword/OPElementEntity.h
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// OPElementEntity.h
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 02/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
|
||||
|
||||
@interface OPElementEntity : NSManagedObject
|
||||
|
||||
@property (nonatomic, retain) NSString *name;
|
||||
@property (nonatomic) int16_t type;
|
||||
@property (nonatomic) int16_t uses;
|
||||
@property (nonatomic) NSTimeInterval lastUsed;
|
||||
@property (nonatomic, retain) NSString *contentUTI;
|
||||
@property (nonatomic) int16_t contentType;
|
||||
|
||||
- (void)use;
|
||||
- (id)content;
|
||||
- (NSString *)contentDescription;
|
||||
|
||||
@end
|
45
OnePassword/OPElementEntity.m
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// OPElementEntity.m
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 02/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OPElementEntity.h"
|
||||
#import "OPAppDelegate.h"
|
||||
|
||||
|
||||
@implementation OPElementEntity
|
||||
|
||||
@dynamic name;
|
||||
@dynamic type;
|
||||
@dynamic uses;
|
||||
@dynamic lastUsed;
|
||||
@dynamic contentUTI;
|
||||
@dynamic contentType;
|
||||
|
||||
- (void)use {
|
||||
|
||||
++self.uses;
|
||||
self.lastUsed = [[NSDate date] timeIntervalSinceReferenceDate];
|
||||
}
|
||||
|
||||
- (id)content {
|
||||
|
||||
if (![self.name length])
|
||||
return nil;
|
||||
|
||||
if (self.type & OPElementTypeCalculated)
|
||||
return OPCalculateContent(self.type, self.name, [OPAppDelegate get].keyPhrase);
|
||||
|
||||
@throw [NSException exceptionWithName:NSInternalInconsistencyException
|
||||
reason:[NSString stringWithFormat:@"Unsupported type: %d", self.type] userInfo:nil];
|
||||
}
|
||||
|
||||
- (NSString *)contentDescription {
|
||||
|
||||
return [[self content] description];
|
||||
}
|
||||
|
||||
@end
|
18
OnePassword/OPElementStoredEntity.h
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// OPElementStoredEntity.h
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 02/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
#import "OPElementEntity.h"
|
||||
|
||||
|
||||
@interface OPElementStoredEntity : OPElementEntity
|
||||
|
||||
@property (nonatomic, retain) id contentObject;
|
||||
|
||||
@end
|
23
OnePassword/OPElementStoredEntity.m
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// OPElementStoredEntity.m
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 02/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OPElementStoredEntity.h"
|
||||
|
||||
|
||||
@implementation OPElementStoredEntity
|
||||
|
||||
@dynamic contentObject;
|
||||
|
||||
- (id)content {
|
||||
|
||||
assert(self.type & OPElementTypeStored);
|
||||
|
||||
return self.contentObject;
|
||||
}
|
||||
|
||||
@end
|
@ -6,8 +6,19 @@
|
||||
// Copyright (c) 2011 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
@interface OPMainViewController : UITableViewController
|
||||
#import "OPTypeViewController.h"
|
||||
#import "OPElementEntity.h"
|
||||
#import "OPSearchDelegate.h"
|
||||
|
||||
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
|
||||
@interface OPMainViewController : UITableViewController <OPTypeDelegate, UITextFieldDelegate, UISearchBarDelegate, OPSearchResultsDelegate>
|
||||
|
||||
@property (strong, nonatomic) OPElementEntity *activeElement;
|
||||
@property (strong, nonatomic) IBOutlet OPSearchDelegate *searchResultsController;
|
||||
@property (weak, nonatomic) IBOutlet UITextField *contentField;
|
||||
@property (weak, nonatomic) IBOutlet UITextView *contentTextView;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *typeLabel;
|
||||
@property (weak, nonatomic) IBOutlet UISegmentedControl *contentType;
|
||||
|
||||
- (IBAction)didChangeContentType:(UISegmentedControl *)sender;
|
||||
|
||||
@end
|
||||
|
@ -7,67 +7,140 @@
|
||||
//
|
||||
|
||||
#import "OPMainViewController.h"
|
||||
#import "OPAppDelegate.h"
|
||||
#import "OPContentViewController.h"
|
||||
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
|
||||
|
||||
@interface OPMainViewController (Private)
|
||||
|
||||
- (void)updateAnimated:(BOOL)animated;
|
||||
- (void)updateWasAnimated:(BOOL)animated;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OPMainViewController
|
||||
|
||||
@synthesize managedObjectContext = _managedObjectContext;
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
[super didReceiveMemoryWarning];
|
||||
// Release any cached data, images, etc that aren't in use.
|
||||
}
|
||||
@synthesize activeElement = _activeElement;
|
||||
@synthesize searchResultsController = _searchResultsController;
|
||||
@synthesize typeLabel = _typeLabel;
|
||||
@synthesize contentType = _contentType;
|
||||
@synthesize contentField = _contentField;
|
||||
@synthesize contentTextView = _contentTextView;
|
||||
|
||||
#pragma mark - View lifecycle
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
|
||||
|
||||
return [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad || interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
|
||||
}
|
||||
|
||||
- (void)viewDidUnload
|
||||
{
|
||||
[super viewDidUnload];
|
||||
// Release any retained subviews of the main view.
|
||||
// e.g. self.myOutlet = nil;
|
||||
}
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
[super viewDidAppear:animated];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated
|
||||
{
|
||||
[super viewWillDisappear:animated];
|
||||
}
|
||||
|
||||
- (void)viewDidDisappear:(BOOL)animated
|
||||
{
|
||||
[super viewDidDisappear:animated];
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
// Return YES for supported orientations
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
|
||||
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
|
||||
} else {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
|
||||
{
|
||||
if ([[segue identifier] isEqualToString:@"showAlternate"]) {
|
||||
if ([[segue identifier] isEqualToString:@"OP_Main_ChooseType"])
|
||||
[[segue destinationViewController] setDelegate:self];
|
||||
if ([[segue identifier] isEqualToString:@"OP_Main_Content"])
|
||||
((OPContentViewController *)[segue destinationViewController]).activeElement = self.activeElement;
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
[self updateAnimated:NO];
|
||||
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
|
||||
// Because IB's edit button doesn't auto-toggle self.editable like editButtonItem does.
|
||||
self.navigationItem.rightBarButtonItem = self.editButtonItem;
|
||||
|
||||
[super viewDidLoad];
|
||||
}
|
||||
|
||||
- (void)viewDidUnload {
|
||||
|
||||
[self setContentField:nil];
|
||||
[self setTypeLabel:nil];
|
||||
|
||||
[self setContentType:nil];
|
||||
[self setContentTextView:nil];
|
||||
[self setSearchResultsController:nil];
|
||||
[super viewDidUnload];
|
||||
}
|
||||
|
||||
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
|
||||
|
||||
[super setEditing:editing animated:animated];
|
||||
|
||||
[self updateAnimated:animated];
|
||||
}
|
||||
|
||||
- (void)updateAnimated:(BOOL)animated {
|
||||
|
||||
[[OPAppDelegate get] saveContext];
|
||||
|
||||
if (animated)
|
||||
[UIView animateWithDuration:0.2 animations:^{
|
||||
[self updateWasAnimated:YES];
|
||||
}];
|
||||
else
|
||||
[self updateWasAnimated:NO];
|
||||
}
|
||||
|
||||
- (void)updateWasAnimated:(BOOL)animated {
|
||||
|
||||
self.typeLabel.text = self.activeElement? NSStringFromOPElementType(self.activeElement.type): @"moo";
|
||||
|
||||
self.contentTextView.alpha = self.contentType.selectedSegmentIndex == OPElementContentTypeNote? 1: 0;
|
||||
self.contentTextView.editable = self.editing && self.activeElement.type & OPElementTypeStored;
|
||||
|
||||
self.contentType.alpha = self.editing && self.activeElement.type & OPElementTypeStored? 1: 0;
|
||||
self.contentType.selectedSegmentIndex = self.activeElement.contentType;
|
||||
|
||||
self.contentField.alpha = self.contentType.selectedSegmentIndex == OPElementContentTypePassword? 1: 0;
|
||||
self.contentField.enabled = self.editing && self.activeElement.type & OPElementTypeStored;
|
||||
self.contentField.clearButtonMode = self.contentField.enabled? UITextFieldViewModeAlways: UITextFieldViewModeNever;
|
||||
self.contentField.text = @"...";
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
|
||||
NSString *contentDescription = self.activeElement.contentDescription;
|
||||
if (contentDescription)
|
||||
[self.activeElement use];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.contentField.text = contentDescription;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Protocols
|
||||
|
||||
- (IBAction)didChangeContentType:(UISegmentedControl *)sender {
|
||||
|
||||
self.activeElement.contentType = self.contentType.selectedSegmentIndex;
|
||||
[self updateAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)didSelectType:(OPElementType)type {
|
||||
|
||||
self.activeElement.type = type;
|
||||
[self updateAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)didSelectElement:(OPElementEntity *)element {
|
||||
|
||||
self.activeElement = element;
|
||||
[self updateAnimated:YES];
|
||||
|
||||
[self.searchDisplayController setActive:NO animated:YES];
|
||||
self.searchDisplayController.searchBar.text = self.activeElement.name;
|
||||
}
|
||||
|
||||
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
|
||||
|
||||
[self updateAnimated:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -11,51 +11,10 @@
|
||||
@implementation OPRecentViewController
|
||||
@dynamic tableView;
|
||||
|
||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
{
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
if (self) {
|
||||
// Custom initialization
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
// Releases the view if it doesn't have a superview.
|
||||
[super didReceiveMemoryWarning];
|
||||
|
||||
// Release any cached data, images, etc that aren't in use.
|
||||
}
|
||||
|
||||
#pragma mark - View lifecycle
|
||||
|
||||
/*
|
||||
// Implement loadView to create a view hierarchy programmatically, without using a nib.
|
||||
- (void)loadView
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
}
|
||||
*/
|
||||
|
||||
- (void)viewDidUnload
|
||||
{
|
||||
[super viewDidUnload];
|
||||
// Release any retained subviews of the main view.
|
||||
// e.g. self.myOutlet = nil;
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
// Return YES for supported orientations
|
||||
return (interfaceOrientation == UIInterfaceOrientationPortrait);
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -1,15 +0,0 @@
|
||||
//
|
||||
// OPSaltedCipherViewController.h
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 30/11/11.
|
||||
// Copyright (c) 2011 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface OPSaltedCipherViewController : UITableViewController
|
||||
|
||||
@property(nonatomic,retain) IBOutlet UITableView *tableView;
|
||||
|
||||
@end
|
@ -1,61 +0,0 @@
|
||||
//
|
||||
// OPSaltedCipherViewController.m
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 30/11/11.
|
||||
// Copyright (c) 2011 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OPSaltedCipherViewController.h"
|
||||
|
||||
@implementation OPSaltedCipherViewController
|
||||
@dynamic tableView;
|
||||
|
||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
{
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
if (self) {
|
||||
// Custom initialization
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
// Releases the view if it doesn't have a superview.
|
||||
[super didReceiveMemoryWarning];
|
||||
|
||||
// Release any cached data, images, etc that aren't in use.
|
||||
}
|
||||
|
||||
#pragma mark - View lifecycle
|
||||
|
||||
/*
|
||||
// Implement loadView to create a view hierarchy programmatically, without using a nib.
|
||||
- (void)loadView
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
}
|
||||
*/
|
||||
|
||||
- (void)viewDidUnload
|
||||
{
|
||||
[super viewDidUnload];
|
||||
// Release any retained subviews of the main view.
|
||||
// e.g. self.myOutlet = nil;
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
// Return YES for supported orientations
|
||||
return (interfaceOrientation == UIInterfaceOrientationPortrait);
|
||||
}
|
||||
|
||||
@end
|
27
OnePassword/OPSearchDelegate.h
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// OPSearchDelegate.h
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 04/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "OPElementEntity.h"
|
||||
|
||||
@protocol OPSearchResultsDelegate <NSObject>
|
||||
|
||||
- (void)didSelectElement:(OPElementEntity *)element;
|
||||
|
||||
@end
|
||||
|
||||
@interface OPSearchDelegate : NSObject <UITableViewDelegate, UITableViewDataSource, UISearchDisplayDelegate, NSFetchedResultsControllerDelegate>
|
||||
|
||||
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet id<OPSearchResultsDelegate> delegate;
|
||||
@property (weak, nonatomic) IBOutlet UISearchDisplayController *searchDisplayController;
|
||||
|
||||
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
@end
|
204
OnePassword/OPSearchDelegate.m
Normal file
@ -0,0 +1,204 @@
|
||||
//
|
||||
// OPSearchDelegate.m
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 04/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OPSearchDelegate.h"
|
||||
#import "OPAppDelegate.h"
|
||||
|
||||
@interface OPSearchDelegate (Private)
|
||||
|
||||
- (NSManagedObjectContext *)managedObjectContext;
|
||||
- (void)update;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OPSearchDelegate
|
||||
@synthesize fetchedResultsController;
|
||||
@synthesize delegate;
|
||||
@synthesize searchDisplayController;
|
||||
|
||||
- (NSManagedObjectContext *)managedObjectContext {
|
||||
|
||||
return [(OPAppDelegate *)[UIApplication sharedApplication].delegate managedObjectContext];
|
||||
}
|
||||
|
||||
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
|
||||
|
||||
[self.searchDisplayController.searchResultsTableView setEditing:self.searchDisplayController.searchContentsController.editing animated:NO];
|
||||
[self update];
|
||||
}
|
||||
|
||||
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
|
||||
|
||||
[self update];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)update {
|
||||
|
||||
NSString *text = self.searchDisplayController.searchBar.text;
|
||||
if (!text)
|
||||
text = @"";
|
||||
|
||||
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([OPElementEntity class])];
|
||||
[fetchRequest setSortDescriptors:
|
||||
[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"uses" ascending:NO]]];
|
||||
[fetchRequest setPredicate:
|
||||
[NSPredicate predicateWithFormat:@"name BEGINSWITH[cd] %@", text]];
|
||||
|
||||
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
|
||||
managedObjectContext:[self managedObjectContext]
|
||||
sectionNameKeyPath:nil cacheName:nil];
|
||||
self.fetchedResultsController.delegate = self;
|
||||
|
||||
NSError *error;
|
||||
if (![self.fetchedResultsController performFetch:&error])
|
||||
err(@"Couldn't fetch elements: %@", error);
|
||||
}
|
||||
|
||||
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
|
||||
|
||||
[self.searchDisplayController.searchResultsTableView beginUpdates];
|
||||
}
|
||||
|
||||
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
|
||||
|
||||
indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section + 1];
|
||||
newIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:newIndexPath.section + 1];
|
||||
|
||||
switch(type) {
|
||||
|
||||
case NSFetchedResultsChangeInsert:
|
||||
[self.searchDisplayController.searchResultsTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||
break;
|
||||
|
||||
case NSFetchedResultsChangeDelete:
|
||||
[self.searchDisplayController.searchResultsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
|
||||
break;
|
||||
|
||||
case NSFetchedResultsChangeUpdate:
|
||||
[self configureCell:[self.searchDisplayController.searchResultsTableView cellForRowAtIndexPath:indexPath]
|
||||
atIndexPath:indexPath];
|
||||
break;
|
||||
|
||||
case NSFetchedResultsChangeMove:
|
||||
[self.searchDisplayController.searchResultsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
|
||||
withRowAnimation:UITableViewRowAnimationFade];
|
||||
[self.searchDisplayController.searchResultsTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
|
||||
withRowAnimation:UITableViewRowAnimationFade];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
|
||||
|
||||
++sectionIndex;
|
||||
|
||||
switch(type) {
|
||||
|
||||
case NSFetchedResultsChangeInsert:
|
||||
[self.searchDisplayController.searchResultsTableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
|
||||
withRowAnimation:UITableViewRowAnimationFade];
|
||||
break;
|
||||
|
||||
case NSFetchedResultsChangeDelete:
|
||||
[self.searchDisplayController.searchResultsTableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
|
||||
withRowAnimation:UITableViewRowAnimationFade];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
|
||||
|
||||
[self.searchDisplayController.searchResultsTableView endUpdates];
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
|
||||
return [[self.fetchedResultsController sections] count] + 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
|
||||
if (--section == -1)
|
||||
return 1;
|
||||
|
||||
return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"OPElementSearch"];
|
||||
if (!cell)
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"OPElementSearch"];
|
||||
|
||||
[self configureCell:cell atIndexPath:indexPath];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section - 1];
|
||||
if (indexPath.section == -1) {
|
||||
cell.textLabel.text = self.searchDisplayController.searchBar.text;
|
||||
cell.detailTextLabel.text = @"New";
|
||||
} else {
|
||||
OPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath];
|
||||
|
||||
cell.textLabel.text = element.name;
|
||||
cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", element.uses];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
OPElementEntity *element;
|
||||
indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section - 1];
|
||||
if (indexPath.section == -1) {
|
||||
element = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([OPElementEntity class])
|
||||
inManagedObjectContext:[self managedObjectContext]];
|
||||
element.name = self.searchDisplayController.searchBar.text;
|
||||
} else
|
||||
element = [self.fetchedResultsController objectAtIndexPath:indexPath];
|
||||
|
||||
[self.delegate didSelectElement:element];
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
|
||||
|
||||
if (--section == -1)
|
||||
return @"";
|
||||
|
||||
return [[[self.fetchedResultsController sections] objectAtIndex:section] name];
|
||||
}
|
||||
|
||||
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
|
||||
|
||||
return [self.fetchedResultsController sectionIndexTitles];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
|
||||
|
||||
return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section - 1];
|
||||
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete) {
|
||||
OPElementEntity *element = [self.fetchedResultsController objectAtIndexPath:indexPath];
|
||||
|
||||
[[self managedObjectContext] deleteObject:element];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
@ -8,6 +8,14 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface OPTypeViewController : UITableViewController
|
||||
@protocol OPTypeDelegate <NSObject>
|
||||
|
||||
- (void)didSelectType:(OPElementType)type;
|
||||
|
||||
@end
|
||||
|
||||
@interface OPTypeViewController : UITableViewController
|
||||
|
||||
@property (nonatomic, weak) id<OPTypeDelegate> delegate;
|
||||
|
||||
@end
|
||||
|
@ -9,43 +9,71 @@
|
||||
#import "OPTypeViewController.h"
|
||||
|
||||
@implementation OPTypeViewController
|
||||
|
||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
{
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
if (self) {
|
||||
// Custom initialization
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
// Releases the view if it doesn't have a superview.
|
||||
[super didReceiveMemoryWarning];
|
||||
|
||||
// Release any cached data, images, etc that aren't in use.
|
||||
}
|
||||
@synthesize delegate;
|
||||
|
||||
#pragma mark - View lifecycle
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view from its nib.
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)viewDidUnload
|
||||
{
|
||||
[super viewDidUnload];
|
||||
// Release any retained subviews of the main view.
|
||||
// e.g. self.myOutlet = nil;
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
|
||||
assert(self.navigationController.topViewController == self);
|
||||
|
||||
OPElementType type;
|
||||
switch (indexPath.section) {
|
||||
case 0: {
|
||||
// Calculated
|
||||
switch (indexPath.row) {
|
||||
case 0:
|
||||
type = OPElementTypeCalculatedLong;
|
||||
break;
|
||||
case 1:
|
||||
type = OPElementTypeCalculatedMedium;
|
||||
break;
|
||||
case 2:
|
||||
type = OPElementTypeCalculatedShort;
|
||||
break;
|
||||
case 3:
|
||||
type = OPElementTypeCalculatedBasic;
|
||||
break;
|
||||
case 4:
|
||||
type = OPElementTypeCalculatedPIN;
|
||||
break;
|
||||
|
||||
default:
|
||||
[NSException raise:NSInternalInconsistencyException
|
||||
format:@"Unsupported row: %d, when selecting calculated element type.", indexPath.row];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
{
|
||||
// Return YES for supported orientations
|
||||
return (interfaceOrientation == UIInterfaceOrientationPortrait);
|
||||
case 1: {
|
||||
// Stored
|
||||
switch (indexPath.row) {
|
||||
case 0:
|
||||
type = OPElementTypeStoredPersonal;
|
||||
break;
|
||||
case 1:
|
||||
type = OPElementTypeStoredDevicePrivate;
|
||||
break;
|
||||
|
||||
default:
|
||||
[NSException raise:NSInternalInconsistencyException
|
||||
format:@"Unsupported row: %d, when selecting stored element type.", indexPath.row];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
[NSException raise:NSInternalInconsistencyException
|
||||
format:@"Unsupported section: %d, when selecting element type.", indexPath.section];
|
||||
}
|
||||
|
||||
[delegate didSelectType:type];
|
||||
[self.navigationController popViewControllerAnimated:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
34
OnePassword/OPTypes.h
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// OPTypes.h
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 02/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef enum {
|
||||
OPElementContentTypePassword,
|
||||
OPElementContentTypeNote,
|
||||
OPElementContentTypePicture,
|
||||
} OPElementContentType;
|
||||
|
||||
typedef enum {
|
||||
OPElementTypeCalculated = 2 << 7,
|
||||
OPElementTypeStored = 2 << 8,
|
||||
} OPElementTypeClass;
|
||||
|
||||
typedef enum {
|
||||
OPElementTypeCalculatedLong = OPElementTypeCalculated | 0x01,
|
||||
OPElementTypeCalculatedMedium = OPElementTypeCalculated | 0x02,
|
||||
OPElementTypeCalculatedShort = OPElementTypeCalculated | 0x03,
|
||||
OPElementTypeCalculatedBasic = OPElementTypeCalculated | 0x04,
|
||||
OPElementTypeCalculatedPIN = OPElementTypeCalculated | 0x05,
|
||||
|
||||
OPElementTypeStoredPersonal = OPElementTypeStored | 0x01,
|
||||
OPElementTypeStoredDevicePrivate = OPElementTypeStored | 0x02,
|
||||
} OPElementType;
|
||||
|
||||
NSString *NSStringFromOPElementType(OPElementType type);
|
||||
NSString *OPCalculateContent(OPElementType type, NSString *name, NSString *keyPhrase);
|
72
OnePassword/OPTypes.m
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// OPTypes.m
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 02/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OPTypes.h"
|
||||
|
||||
|
||||
NSString *NSStringFromOPElementType(OPElementType type) {
|
||||
|
||||
switch (type) {
|
||||
case OPElementTypeCalculatedLong:
|
||||
return @"Long";
|
||||
|
||||
case OPElementTypeCalculatedMedium:
|
||||
return @"Medium";
|
||||
|
||||
case OPElementTypeCalculatedShort:
|
||||
return @"Short";
|
||||
|
||||
case OPElementTypeCalculatedBasic:
|
||||
return @"Basic";
|
||||
|
||||
case OPElementTypeCalculatedPIN:
|
||||
return @"PIN";
|
||||
|
||||
case OPElementTypeStoredPersonal:
|
||||
return @"Personal";
|
||||
|
||||
case OPElementTypeStoredDevicePrivate:
|
||||
return @"Device Private";
|
||||
|
||||
default:
|
||||
[NSException raise:NSInternalInconsistencyException format:@"Type not supported: %d", type];
|
||||
}
|
||||
}
|
||||
|
||||
static NSDictionary *OPTypes_ciphers = nil;
|
||||
NSString *OPCalculateContent(OPElementType type, NSString *name, NSString *keyPhrase) {
|
||||
|
||||
assert(type & OPElementTypeCalculated);
|
||||
|
||||
if (OPTypes_ciphers == nil)
|
||||
OPTypes_ciphers = [NSDictionary dictionaryWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ciphers"
|
||||
withExtension:@"plist"]];
|
||||
|
||||
// Determine the hash whose bytes will be used for calculating a password: md4(name-keyPhrase)
|
||||
assert(name && keyPhrase);
|
||||
NSData *keyHash = [[NSString stringWithFormat:@"%@-%@", name, keyPhrase] hashWith:PearlDigestMD4];
|
||||
const char *keyBytes = keyHash.bytes;
|
||||
|
||||
// Determine the cipher from the first hash byte.
|
||||
assert([keyHash length]);
|
||||
NSArray *typeCiphers = [[OPTypes_ciphers valueForKey:@"OPElementTypeCalculated"] valueForKey:NSStringFromOPElementType(type)];
|
||||
NSString *cipher = [typeCiphers objectAtIndex:keyBytes[0] % [typeCiphers count]];
|
||||
|
||||
// Encode the content, character by character, using subsequent hash bytes and the cipher.
|
||||
assert([keyHash length] >= [cipher length] + 1);
|
||||
NSMutableString *content = [NSMutableString stringWithCapacity:[cipher length]];
|
||||
for (NSUInteger c = 0; c < [cipher length]; ++c) {
|
||||
const char keyByte = keyBytes[c + 1];
|
||||
NSString *cipherClass = [cipher substringWithRange:NSMakeRange(c, 1)];
|
||||
NSString *cipherClassCharacters = [[OPTypes_ciphers valueForKey:@"OPCharacterClasses"] valueForKey:cipherClass];
|
||||
|
||||
[content appendString:[cipherClassCharacters substringWithRange:NSMakeRange(keyByte % [cipherClassCharacters length], 1)]];
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
@ -26,6 +26,8 @@
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIApplicationExitsOnSuspend</key>
|
||||
<true/>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>MainStoryboard_iPhone</string>
|
||||
<key>UIMainStoryboardFile~ipad</key>
|
||||
|
@ -14,4 +14,13 @@
|
||||
#import <CoreData/CoreData.h>
|
||||
#endif
|
||||
|
||||
#import "Pearl-Prefix.pch"
|
||||
#define PEARL
|
||||
#define PEARL_CRYPTO
|
||||
#define PEARL_UIKIT
|
||||
|
||||
#import "Pearl.h"
|
||||
#import "Pearl-Crypto.h"
|
||||
#import "Pearl-UIKit.h"
|
||||
|
||||
#import "OPTypes.h"
|
||||
#import "OPConfig.h"
|
||||
|
@ -1,4 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model name="Test1.xcdatamodel" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
|
||||
<elements/>
|
||||
<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="872" systemVersion="11C74" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
|
||||
<entity name="OPElementEntity" representedClassName="OPElementEntity" syncable="YES">
|
||||
<attribute name="contentType" optional="YES" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
|
||||
<attribute name="contentUTI" attributeType="String" defaultValueString="public.plain-text" syncable="YES"/>
|
||||
<attribute name="lastUsed" attributeType="Date" syncable="YES"/>
|
||||
<attribute name="name" attributeType="String" indexed="YES" syncable="YES"/>
|
||||
<attribute name="type" attributeType="Integer 16" defaultValueString="257" syncable="YES"/>
|
||||
<attribute name="uses" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
|
||||
</entity>
|
||||
<entity name="OPElementStoredEntity" representedClassName="OPElementStoredEntity" parentEntity="OPElementEntity" syncable="YES">
|
||||
<attribute name="contentObject" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
|
||||
</entity>
|
||||
<fetchRequest name="OPSearchElement" entity="OPElementEntity" predicateString="name BEGINSWITH "$query""/>
|
||||
<elements>
|
||||
<element name="OPElementEntity" positionX="160" positionY="192" width="128" height="135"/>
|
||||
<element name="OPElementStoredEntity" positionX="160" positionY="192" width="128" height="75"/>
|
||||
</elements>
|
||||
</model>
|
55
OnePassword/ciphers.plist
Normal file
@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>OPElementTypeCalculated</key>
|
||||
<dict>
|
||||
<key>Long</key>
|
||||
<array>
|
||||
<string>CvcvCvcvnoCvcv</string>
|
||||
<string>CvcvnoCvcvCvcv</string>
|
||||
<string>CvcvCvcvCvcvno</string>
|
||||
</array>
|
||||
<key>Medium</key>
|
||||
<array>
|
||||
<string>CvcnoCvc</string>
|
||||
<string>CvcCvcno</string>
|
||||
</array>
|
||||
<key>Short</key>
|
||||
<array>
|
||||
<string>Cvcn</string>
|
||||
</array>
|
||||
<key>Basic</key>
|
||||
<array>
|
||||
<string>aaanaaan</string>
|
||||
<string>aannaaan</string>
|
||||
<string>aaannaaa</string>
|
||||
</array>
|
||||
<key>PIN</key>
|
||||
<array>
|
||||
<string>nnnn</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>OPCharacterClasses</key>
|
||||
<dict>
|
||||
<key>V</key>
|
||||
<string>AEIOU</string>
|
||||
<key>C</key>
|
||||
<string>BCDFGHJKLMNPQRSTVWXYZ</string>
|
||||
<key>v</key>
|
||||
<string>aeiou</string>
|
||||
<key>c</key>
|
||||
<string>bcdfghjklmnpqrstvwxyz</string>
|
||||
<key>A</key>
|
||||
<string>AEIOUBCDFGHJKLMNPQRSTVWXYZ</string>
|
||||
<key>a</key>
|
||||
<string>AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz</string>
|
||||
<key>n</key>
|
||||
<string>0123456789</string>
|
||||
<key>o</key>
|
||||
<string>!@#$%^&*()</string>
|
||||
<key>X</key>
|
||||
<string>AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
BIN
OnePassword/divider/Bold_Lines.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
OnePassword/divider/Box.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
OnePassword/divider/Dashed_Divider.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
OnePassword/divider/Dashed_Divider_.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
OnePassword/divider/Dashed_Divider_Highlight.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
OnePassword/divider/Dotted_Dividers.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
OnePassword/divider/Doubble_Shadow_.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
OnePassword/divider/Double.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
OnePassword/divider/Double_Page.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
OnePassword/divider/Double_Page_2.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
OnePassword/divider/Double_Shadow.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
OnePassword/divider/Double_With_White.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
OnePassword/divider/Double_With_White_Strong.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
11
OnePassword/divider/Help.rtf
Normal file
@ -0,0 +1,11 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\margl1440\margr1440\vieww9000\viewh8400\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
|
||||
|
||||
\f0\fs24 \cf0 Hello,\
|
||||
Thank you for purchasing my item. \
|
||||
To use the dividers, just drag and drop the folder containing the divider you want to use. If you want to expand the divider you can resize it. \
|
||||
If you want to change the color of a divider you can use the color overlay filter. \
|
||||
Thanks again, if you need help please contact me via GraphicRiver. }
|
BIN
OnePassword/divider/Highlight_Smooth_Divider.png
Normal file
After Width: | Height: | Size: 9.0 KiB |
BIN
OnePassword/divider/Highlight_Smooth_Divider_copy.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
OnePassword/divider/Highlight_StrongDivider_copy_3.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
OnePassword/divider/Page.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
OnePassword/divider/Rectangular.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
OnePassword/divider/Rounded.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
BIN
OnePassword/divider/Rounded_Inverted.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
OnePassword/divider/Simple.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
OnePassword/divider/Simple_Divider.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
OnePassword/divider/Simple_Divider_.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
OnePassword/divider/Simple_Divider_Strong.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
OnePassword/divider/Simple_Divider__Strong.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
OnePassword/divider/Single_Shadow.png
Normal file
After Width: | Height: | Size: 9.0 KiB |
BIN
OnePassword/divider/Single_Shadow_.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
OnePassword/divider/Smooth_Divider.png
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
OnePassword/divider/Square.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
OnePassword/divider/White_Rectangular.png
Normal file
After Width: | Height: | Size: 21 KiB |
9
OnePassword/types.c
Normal file
@ -0,0 +1,9 @@
|
||||
//
|
||||
// types.c
|
||||
// OnePassword
|
||||
//
|
||||
// Created by Maarten Billemont on 02/01/12.
|
||||
// Copyright (c) 2012 Lyndir. All rights reserved.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|