Merge branch 'master' of github.com:mssun/passforios
This commit is contained in:
commit
83e55403e5
15 changed files with 315 additions and 139 deletions
|
|
@ -3,6 +3,7 @@
|
|||
# Pass
|
||||
[](https://github.com/mssun/pass-ios/releases)
|
||||

|
||||
[](https://gitter.im/passforios/passforios)
|
||||
|
||||
Pass is an iOS client compatible with [ZX2C4's Pass command line
|
||||
application](http://www.passwordstore.org/). It is a password manager using
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@
|
|||
DCC408C71E307DBB00F29B0E /* SVProgressHUD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC408C61E307DBB00F29B0E /* SVProgressHUD.framework */; };
|
||||
DCDDEAB01E4639F300F68193 /* LabelTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = DCDDEAAF1E4639F300F68193 /* LabelTableViewCell.xib */; };
|
||||
DCDDEAB31E4896BF00F68193 /* PasswordDetailTitleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCDDEAB11E4896BF00F68193 /* PasswordDetailTitleTableViewCell.swift */; };
|
||||
DCE6C2671E71261C003038C6 /* PasswordWithFolderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCE6C2651E71261C003038C6 /* PasswordWithFolderTableViewCell.swift */; };
|
||||
DCE6C2681E71261C003038C6 /* PasswordWithFolderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = DCE6C2661E71261C003038C6 /* PasswordWithFolderTableViewCell.xib */; };
|
||||
DCFB779A1E4F3BCF008DE471 /* TitleTextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFB77981E4F3BCF008DE471 /* TitleTextFieldTableViewCell.swift */; };
|
||||
DCFB779B1E4F3BCF008DE471 /* TitleTextFieldTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = DCFB77991E4F3BCF008DE471 /* TitleTextFieldTableViewCell.xib */; };
|
||||
DCFB779E1E4F40C7008DE471 /* FillPasswordTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFB779C1E4F40C7008DE471 /* FillPasswordTableViewCell.swift */; };
|
||||
|
|
@ -116,6 +118,8 @@
|
|||
DCC408C91E30BA1300F29B0E /* pass.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = pass.xcdatamodel; sourceTree = "<group>"; };
|
||||
DCDDEAAF1E4639F300F68193 /* LabelTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LabelTableViewCell.xib; sourceTree = "<group>"; };
|
||||
DCDDEAB11E4896BF00F68193 /* PasswordDetailTitleTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordDetailTitleTableViewCell.swift; sourceTree = "<group>"; };
|
||||
DCE6C2651E71261C003038C6 /* PasswordWithFolderTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordWithFolderTableViewCell.swift; sourceTree = "<group>"; };
|
||||
DCE6C2661E71261C003038C6 /* PasswordWithFolderTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PasswordWithFolderTableViewCell.xib; sourceTree = "<group>"; };
|
||||
DCFB77981E4F3BCF008DE471 /* TitleTextFieldTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TitleTextFieldTableViewCell.swift; sourceTree = "<group>"; };
|
||||
DCFB77991E4F3BCF008DE471 /* TitleTextFieldTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TitleTextFieldTableViewCell.xib; sourceTree = "<group>"; };
|
||||
DCFB779C1E4F40C7008DE471 /* FillPasswordTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FillPasswordTableViewCell.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -222,6 +226,8 @@
|
|||
DC037CBD1E4ED4E100609409 /* TextViewTableViewCell.swift */,
|
||||
DC037CBE1E4ED4E100609409 /* TextViewTableViewCell.xib */,
|
||||
DCFB77AA1E503729008DE471 /* ContentTableViewCell.swift */,
|
||||
DCE6C2651E71261C003038C6 /* PasswordWithFolderTableViewCell.swift */,
|
||||
DCE6C2661E71261C003038C6 /* PasswordWithFolderTableViewCell.xib */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -348,6 +354,7 @@
|
|||
DCDDEAB01E4639F300F68193 /* LabelTableViewCell.xib in Resources */,
|
||||
DC917BDC1E2E8231000FDF54 /* Main.storyboard in Resources */,
|
||||
A2802BFA1E70813A00879216 /* SliderTableViewCell.xib in Resources */,
|
||||
DCE6C2681E71261C003038C6 /* PasswordWithFolderTableViewCell.xib in Resources */,
|
||||
DCFB779B1E4F3BCF008DE471 /* TitleTextFieldTableViewCell.xib in Resources */,
|
||||
DCFB779F1E4F40C7008DE471 /* FillPasswordTableViewCell.xib in Resources */,
|
||||
DC037CC01E4ED4E100609409 /* TextViewTableViewCell.xib in Resources */,
|
||||
|
|
@ -441,6 +448,7 @@
|
|||
DC4914961E434301007FF592 /* LabelTableViewCell.swift in Sources */,
|
||||
DC5F385B1E56AADB00C69ACA /* PGPKeyArmorSettingTableViewController.swift in Sources */,
|
||||
DCAAF7451E2FA66800AB94BC /* SettingsTableViewController.swift in Sources */,
|
||||
DCE6C2671E71261C003038C6 /* PasswordWithFolderTableViewCell.swift in Sources */,
|
||||
DCFB77A71E502DF9008DE471 /* EditPasswordTableViewController.swift in Sources */,
|
||||
DCA0499A1E335CC800522E8F /* GitServerSettingTableViewController.swift in Sources */,
|
||||
DCDDEAB31E4896BF00F68193 /* PasswordDetailTitleTableViewCell.swift in Sources */,
|
||||
|
|
@ -589,7 +597,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 23;
|
||||
CURRENT_PROJECT_VERSION = 24;
|
||||
DEFINES_MODULE = NO;
|
||||
DEVELOPMENT_TEAM = 4WDM8E95VU;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
|
|
@ -621,7 +629,7 @@
|
|||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 23;
|
||||
CURRENT_PROJECT_VERSION = 24;
|
||||
DEFINES_MODULE = NO;
|
||||
DEVELOPMENT_TEAM = 4WDM8E95VU;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="YoR-iB-XAd">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12106.1" systemVersion="16E183b" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="YoR-iB-XAd">
|
||||
<device id="retina5_5" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12074.1"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
|
@ -284,28 +284,37 @@
|
|||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="commitLogCell" textLabel="F6l-ge-iaV" detailTextLabel="WA3-eC-AH9" style="IBUITableViewCellStyleValue1" id="OfB-1N-1Am">
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="commitLogCell" id="OfB-1N-1Am">
|
||||
<rect key="frame" x="0.0" y="28" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="OfB-1N-1Am" id="fh0-au-C6q">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.666666666666664"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="F6l-ge-iaV">
|
||||
<rect key="frame" x="15" y="13" width="30" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" tag="101" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00/00/00" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hj4-EP-LFW">
|
||||
<rect key="frame" x="15" y="8" width="67" height="28"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="67" id="jNO-Xy-H99"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" tag="102" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Edit password for totp-secret/github.com using vi." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VFa-a4-XsP">
|
||||
<rect key="frame" x="82" y="12.666666666666664" width="324" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Detail" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="WA3-eC-AH9">
|
||||
<rect key="frame" x="359.66666666666669" y="13" width="39.333333333333336" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="VFa-a4-XsP" secondAttribute="trailing" id="CYg-3q-qmy"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="hj4-EP-LFW" secondAttribute="bottom" id="T4H-IJ-u7V"/>
|
||||
<constraint firstItem="hj4-EP-LFW" firstAttribute="leading" secondItem="fh0-au-C6q" secondAttribute="leadingMargin" constant="7" id="V6T-7K-TqS"/>
|
||||
<constraint firstItem="hj4-EP-LFW" firstAttribute="top" secondItem="fh0-au-C6q" secondAttribute="topMargin" id="ZLa-MU-m1x"/>
|
||||
<constraint firstItem="VFa-a4-XsP" firstAttribute="leading" secondItem="hj4-EP-LFW" secondAttribute="trailing" id="bDo-Wj-KTw"/>
|
||||
<constraint firstItem="VFa-a4-XsP" firstAttribute="centerY" secondItem="hj4-EP-LFW" secondAttribute="centerY" id="jK3-7C-cIS"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
|
|
@ -317,7 +326,7 @@
|
|||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dk5-pb-UNe" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="6305" y="1403"/>
|
||||
<point key="canvasLocation" x="6304.347826086957" y="1402.9891304347827"/>
|
||||
</scene>
|
||||
<!--Git Server-->
|
||||
<scene sceneID="Obl-ql-ILG">
|
||||
|
|
@ -331,10 +340,10 @@
|
|||
<tableViewSection headerTitle="Git Repository URL" id="pbe-W6-w4V">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="gitRepositoryURLTabelViewCell" rowHeight="52" id="FRr-pf-aPO">
|
||||
<rect key="frame" x="0.0" y="55" width="414" height="52"/>
|
||||
<rect key="frame" x="0.0" y="55.5" width="414" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="FRr-pf-aPO" id="60A-PS-qGe">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Git Repository URL" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="EVT-VU-sCi">
|
||||
|
|
@ -357,10 +366,10 @@
|
|||
<tableViewSection headerTitle="Username" id="fRu-A2-SCk">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="usernameTableVIewCell" rowHeight="52" id="tnj-5U-kMB">
|
||||
<rect key="frame" x="0.0" y="163" width="414" height="52"/>
|
||||
<rect key="frame" x="0.0" y="163.5" width="414" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tnj-5U-kMB" id="f0c-pI-MSJ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Username" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="TMg-Gk-7nG">
|
||||
|
|
@ -383,10 +392,10 @@
|
|||
<tableViewSection headerTitle="Authentication Method" id="h0N-tI-shZ">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="2" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="KrP-nb-haa">
|
||||
<rect key="frame" x="0.0" y="271" width="414" height="44"/>
|
||||
<rect key="frame" x="0.0" y="271.5" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KrP-nb-haa" id="1uB-oE-kfI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Password" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LfQ-Af-j2O">
|
||||
|
|
@ -414,10 +423,10 @@
|
|||
<inset key="separatorInset" minX="62" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" accessoryType="detailButton" hidesAccessoryWhenEditing="NO" indentationLevel="2" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="Qmt-bo-CuJ">
|
||||
<rect key="frame" x="0.0" y="315" width="414" height="44"/>
|
||||
<rect key="frame" x="0.0" y="315.5" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Qmt-bo-CuJ" id="p3u-8b-h3U">
|
||||
<rect key="frame" x="0.0" y="0.0" width="367" height="43"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="367" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SSH Key" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ezz-76-a53">
|
||||
|
|
@ -494,7 +503,7 @@
|
|||
<rect key="frame" x="0.0" y="35" width="414" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="BYZ-9g-xZy" id="Zfn-rK-sN1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dWi-eh-7Eq">
|
||||
|
|
@ -524,7 +533,7 @@
|
|||
<rect key="frame" x="0.0" y="87" width="414" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="vpk-J8-j7t" id="1td-qT-6ts">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Private Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qht-RC-Yeg">
|
||||
|
|
@ -779,7 +788,7 @@
|
|||
<rect key="frame" x="0.0" y="35" width="414" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Jy1-4S-Lvf" id="tJE-ww-okf">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Oys-xP-ZrB">
|
||||
|
|
@ -809,7 +818,7 @@
|
|||
<rect key="frame" x="0.0" y="87" width="414" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="MA5-lE-8dT" id="pTv-Wj-psC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Private Key URL" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="C2w-dd-roS">
|
||||
|
|
@ -839,7 +848,7 @@
|
|||
<rect key="frame" x="0.0" y="139" width="414" height="52"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="yER-vT-YTO" id="Mip-zw-xLu">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="52"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="51.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Passphrase" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Rnj-2x-ksO">
|
||||
|
|
@ -934,14 +943,14 @@
|
|||
<sections>
|
||||
<tableViewSection id="ugP-R2-9M7">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="K2K-Bx-g7Z" style="IBUITableViewCellStyleDefault" id="NI1-Kd-hyH">
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="Jwg-mt-woS" style="IBUITableViewCellStyleDefault" id="tHt-Ro-0HF" userLabel="Discard Changes Table View Cell">
|
||||
<rect key="frame" x="0.0" y="35" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="NI1-Kd-hyH" id="yLe-T2-TWF">
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tHt-Ro-0HF" id="Epj-ei-NtS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.666666666666664"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Erase All Password Store Data" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="K2K-Bx-g7Z">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Discard All Local Changes" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Jwg-mt-woS">
|
||||
<rect key="frame" x="15" y="0.0" width="384" height="43.666666666666664"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
|
|
@ -951,14 +960,18 @@
|
|||
</subviews>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="Jwg-mt-woS" style="IBUITableViewCellStyleDefault" id="tHt-Ro-0HF" userLabel="Discard Changes Table View Cell">
|
||||
<rect key="frame" x="0.0" y="79" width="414" height="44"/>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection id="ujw-Wl-vs1">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" textLabel="K2K-Bx-g7Z" style="IBUITableViewCellStyleDefault" id="NI1-Kd-hyH">
|
||||
<rect key="frame" x="0.0" y="115" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tHt-Ro-0HF" id="Epj-ei-NtS">
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="NI1-Kd-hyH" id="yLe-T2-TWF">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="43.666666666666664"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Discard All Local Changes" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Jwg-mt-woS">
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Erase All Password Store Data" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="K2K-Bx-g7Z">
|
||||
<rect key="frame" x="15" y="0.0" width="384" height="43.666666666666664"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
|
|
@ -1097,7 +1110,7 @@
|
|||
<rect key="frame" x="0.0" y="35" width="414" height="170"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Pv0-ev-stj" id="ywz-II-W1g">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="170"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="169.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" delaysContentTouches="NO" canCancelContentTouches="NO" bouncesZoom="NO" editable="NO" usesAttributedText="YES" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xzQ-5d-kdL">
|
||||
|
|
@ -1155,7 +1168,7 @@
|
|||
<rect key="frame" x="0.0" y="261" width="414" height="160"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Lom-iT-l16" id="eya-Tv-r0q">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="160"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="159.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oyB-oI-1fS">
|
||||
|
|
@ -1211,7 +1224,7 @@ pfZ36xQbOAQYKKf6ZTT5R/Y=
|
|||
<rect key="frame" x="0.0" y="477" width="414" height="160"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="J8U-ev-FRQ" id="eb0-vb-Fcc">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="160"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="159.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lrQ-Ln-ZOv">
|
||||
|
|
|
|||
|
|
@ -10,22 +10,48 @@ import UIKit
|
|||
|
||||
class AboutRepositoryTableViewController: BasicStaticTableViewController {
|
||||
|
||||
var needRefresh = false
|
||||
var indicatorLabel: UILabel!
|
||||
var indicator: UIActivityIndicatorView!
|
||||
|
||||
override func viewDidLoad() {
|
||||
navigationItemTitle = "About Repository"
|
||||
super.viewDidLoad()
|
||||
let indicatorLable = UILabel(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 21))
|
||||
indicatorLable.center = CGPoint(x: view.frame.size.width / 2, y: view.frame.size.height * 0.382 + 22)
|
||||
indicatorLable.backgroundColor = UIColor.clear
|
||||
indicatorLable.textColor = UIColor.gray
|
||||
indicatorLable.text = "calculating"
|
||||
indicatorLable.textAlignment = .center
|
||||
indicatorLable.font = UIFont.preferredFont(forTextStyle: .footnote)
|
||||
let indicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
|
||||
indicator.center = CGPoint(x: view.frame.size.width / 2, y: view.frame.size.height * 0.382)
|
||||
indicator.startAnimating()
|
||||
tableView.addSubview(indicator)
|
||||
tableView.addSubview(indicatorLable)
|
||||
|
||||
indicatorLabel = UILabel(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 21))
|
||||
indicatorLabel.center = CGPoint(x: view.frame.size.width / 2, y: view.frame.size.height * 0.382 + 22)
|
||||
indicatorLabel.backgroundColor = UIColor.clear
|
||||
indicatorLabel.textColor = UIColor.gray
|
||||
indicatorLabel.text = "calculating"
|
||||
indicatorLabel.textAlignment = .center
|
||||
indicatorLabel.font = UIFont.preferredFont(forTextStyle: .footnote)
|
||||
indicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
|
||||
indicator.center = CGPoint(x: view.frame.size.width / 2, y: view.frame.size.height * 0.382)
|
||||
tableView.addSubview(indicator)
|
||||
tableView.addSubview(indicatorLabel)
|
||||
|
||||
setTableData()
|
||||
addNotificationObservers()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
if needRefresh {
|
||||
indicatorLabel.text = "reloading"
|
||||
setTableData()
|
||||
needRefresh = false
|
||||
}
|
||||
}
|
||||
|
||||
private func setTableData() {
|
||||
|
||||
// clear current contents (if any)
|
||||
self.tableData.removeAll(keepingCapacity: true)
|
||||
self.tableView.reloadData()
|
||||
indicatorLabel.isHidden = false
|
||||
indicator.startAnimating()
|
||||
|
||||
// reload the table
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
let numberFormatter = NumberFormatter()
|
||||
numberFormatter.numberStyle = NumberFormatter.Style.decimal
|
||||
|
|
@ -59,11 +85,19 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController {
|
|||
[.title: "Commit Logs", .action: "segue", .link: "showCommitLogsSegue"],
|
||||
],
|
||||
]
|
||||
indicator.stopAnimating()
|
||||
indicatorLable.isHidden = true
|
||||
self?.indicator.stopAnimating()
|
||||
self?.indicatorLabel.isHidden = true
|
||||
self?.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func addNotificationObservers() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(setNeedRefresh), name: NSNotification.Name(rawValue: "passwordUpdated"), object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(setNeedRefresh), name: NSNotification.Name(rawValue: "passwordStoreErased"), object: nil)
|
||||
}
|
||||
|
||||
func setNeedRefresh() {
|
||||
needRefresh = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,15 +35,24 @@ class AdvancedSettingsTableViewController: UITableViewController {
|
|||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
} else if tableView.cellForRow(at: indexPath) == discardChangesTableViewCell {
|
||||
let alert = UIAlertController(title: "Discard All Changes?", message: "Do you want to permanently discard all changes to the local copy of your password data? You cannot undo this action.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "Discard All Changesa", style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in
|
||||
alert.addAction(UIAlertAction(title: "Discard All Changes", style: UIAlertActionStyle.destructive, handler: {[unowned self] (action) -> Void in
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
SVProgressHUD.show(withStatus: "Resetting ...")
|
||||
DispatchQueue.main.async {
|
||||
do {
|
||||
let numberDiscarded = try PasswordStore.shared.reset()
|
||||
NotificationCenter.default.post(Notification(name: Notification.Name("passwordStoreChangeDiscarded")))
|
||||
if numberDiscarded > 0 {
|
||||
NotificationCenter.default.post(Notification(name: Notification.Name("passwordStoreChangeDiscarded")))
|
||||
}
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
SVProgressHUD.showSuccess(withStatus: "Discarded \(numberDiscarded) commits")
|
||||
switch numberDiscarded {
|
||||
case 0:
|
||||
SVProgressHUD.showSuccess(withStatus: "No local commits")
|
||||
case 1:
|
||||
SVProgressHUD.showSuccess(withStatus: "Discarded 1 commit")
|
||||
default:
|
||||
SVProgressHUD.showSuccess(withStatus: "Discarded \(numberDiscarded) commits")
|
||||
}
|
||||
SVProgressHUD.dismiss(withDelay: 1)
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
|
|
|
|||
|
|
@ -29,8 +29,10 @@ class CommitLogsTableViewController: UITableViewController {
|
|||
formatter.dateStyle = DateFormatter.Style.short
|
||||
formatter.timeStyle = .none
|
||||
let dateString = formatter.string(from: commits[indexPath.row].commitDate)
|
||||
cell.textLabel?.text = dateString
|
||||
cell.detailTextLabel?.text = commits[indexPath.row].message
|
||||
let dateLabel = cell.viewWithTag(101) as! UILabel
|
||||
let messageLabel = cell.viewWithTag(102) as! UILabel
|
||||
dateLabel.text = dateString
|
||||
messageLabel.text = commits[indexPath.row].message
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ class GeneralSettingsTableViewController: BasicStaticTableViewController {
|
|||
}
|
||||
|
||||
func tapHideUnknownSwitchDetailButton(_ sender: Any?) {
|
||||
let alertMessage = "Only \"key: value\" format in additional fields is supported. Unsupported fields will be given \"unkown\" keys. Turn on this switch to hide unsupported fields."
|
||||
let alertMessage = "Only \"key: value\" format in additional fields is supported. Unsupported fields will be given \"unknown\" keys. Turn on this switch to hide unsupported fields."
|
||||
let alertTitle = "Hide Unknown Fields"
|
||||
Utils.alert(title: alertTitle, message: alertMessage, controller: self, completion: nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
var password: Password?
|
||||
var passwordImage: UIImage?
|
||||
var oneTimePasswordIndexPath : IndexPath?
|
||||
var shouldPopCurrentView = false
|
||||
|
||||
let indicatorLable: UILabel = {
|
||||
let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 21))
|
||||
|
|
@ -62,23 +63,12 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
|
||||
var tableData = Array<TableSection>()
|
||||
|
||||
private func generateCategoryText() -> String {
|
||||
var passwordCategoryArray: [String] = []
|
||||
var parent = passwordEntity?.parent
|
||||
while parent != nil {
|
||||
passwordCategoryArray.append(parent!.name!)
|
||||
parent = parent!.parent
|
||||
}
|
||||
passwordCategoryArray.reverse()
|
||||
return passwordCategoryArray.joined(separator: " > ")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
tableView.register(UINib(nibName: "LabelTableViewCell", bundle: nil), forCellReuseIdentifier: "labelCell")
|
||||
tableView.register(UINib(nibName: "PasswordDetailTitleTableViewCell", bundle: nil), forCellReuseIdentifier: "passwordDetailTitleTableViewCell")
|
||||
|
||||
passwordCategoryText = generateCategoryText()
|
||||
passwordCategoryText = passwordEntity!.getCategoryText()
|
||||
|
||||
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(PasswordDetailTableViewController.tapMenu(recognizer:)))
|
||||
tableView.addGestureRecognizer(tapGesture)
|
||||
|
|
@ -118,6 +108,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
}
|
||||
|
||||
self.setupUpdateOneTimePassword()
|
||||
self.addNotificationObservers()
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -386,4 +377,22 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
|||
return true
|
||||
}
|
||||
|
||||
private func addNotificationObservers() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(setShouldPopCurrentView), name: NSNotification.Name(rawValue: "passwordStoreChangeDiscarded"), object: nil)
|
||||
}
|
||||
|
||||
func setShouldPopCurrentView() {
|
||||
self.shouldPopCurrentView = true
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
if self.shouldPopCurrentView {
|
||||
let alert = UIAlertController(title: "Notice", message: "All previous local changes have been discarded. Your current Password Store will be shown.", preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {_ in
|
||||
_ = self.navigationController?.popViewController(animated: true)
|
||||
}))
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
tableView.insertSubview(refreshControl, at: 0)
|
||||
SVProgressHUD.setDefaultMaskType(.black)
|
||||
updateRefreshControlTitle()
|
||||
tableView.register(UINib(nibName: "PasswordWithFolderTableViewCell", bundle: nil), forCellReuseIdentifier: "passwordWithFolderTableViewCell")
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
|
|
@ -186,26 +187,41 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "passwordTableViewCell", for: indexPath)
|
||||
let entry = getPasswordEntry(by: indexPath)
|
||||
if !entry.isDir {
|
||||
if entry.passwordEntity!.synced {
|
||||
cell.textLabel?.text = entry.title
|
||||
} else {
|
||||
cell.textLabel?.text = "↻ \(entry.title)"
|
||||
}
|
||||
let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressAction(_:)))
|
||||
longPressGestureRecognizer.minimumPressDuration = 0.6
|
||||
if Defaults[.isShowFolderOn] {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "passwordTableViewCell", for: indexPath)
|
||||
|
||||
let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressAction(_:)))
|
||||
longPressGestureRecognizer.minimumPressDuration = 0.6
|
||||
cell.addGestureRecognizer(longPressGestureRecognizer)
|
||||
cell.accessoryType = .none
|
||||
cell.detailTextLabel?.text = ""
|
||||
let entry = getPasswordEntry(by: indexPath)
|
||||
if !entry.isDir {
|
||||
if entry.passwordEntity!.synced {
|
||||
cell.textLabel?.text = entry.title
|
||||
} else {
|
||||
cell.textLabel?.text = "↻ \(entry.title)"
|
||||
}
|
||||
|
||||
cell.addGestureRecognizer(longPressGestureRecognizer)
|
||||
cell.accessoryType = .none
|
||||
cell.detailTextLabel?.text = ""
|
||||
} else {
|
||||
cell.textLabel?.text = "\(entry.title)"
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
cell.detailTextLabel?.text = "\(entry.passwordEntity?.children?.count ?? 0)"
|
||||
}
|
||||
return cell
|
||||
} else {
|
||||
cell.textLabel?.text = "\(entry.title)"
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
cell.detailTextLabel?.text = "\(entry.passwordEntity?.children?.count ?? 0)"
|
||||
let passwordWithFolderCell = tableView.dequeueReusableCell(withIdentifier: "passwordWithFolderTableViewCell", for: indexPath) as! PasswordWithFolderTableViewCell
|
||||
let entry = getPasswordEntry(by: indexPath)
|
||||
if entry.passwordEntity!.synced {
|
||||
passwordWithFolderCell.passwordLabel?.text = entry.title
|
||||
} else {
|
||||
passwordWithFolderCell.passwordLabel?.text = "↻ \(entry.title)"
|
||||
}
|
||||
passwordWithFolderCell.folderLabel.text = entry.passwordEntity?.getCategoryText()
|
||||
passwordWithFolderCell.addGestureRecognizer(longPressGestureRecognizer)
|
||||
return passwordWithFolderCell
|
||||
}
|
||||
return cell
|
||||
|
||||
}
|
||||
|
||||
private func getPasswordEntry(by indexPath: IndexPath) -> PasswordsTableEntry {
|
||||
|
|
@ -222,7 +238,11 @@ class PasswordsViewController: UIViewController, UITableViewDataSource, UITableV
|
|||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let entry = getPasswordEntry(by: indexPath)
|
||||
if !entry.isDir {
|
||||
performSegue(withIdentifier: "showPasswordDetail", sender: tableView.cellForRow(at: indexPath))
|
||||
let segueIdentifier = "showPasswordDetail"
|
||||
let sender = tableView.cellForRow(at: indexPath)
|
||||
if shouldPerformSegue(withIdentifier: segueIdentifier, sender: sender) {
|
||||
performSegue(withIdentifier: segueIdentifier, sender: sender)
|
||||
}
|
||||
} else {
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
searchController.isActive = false
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>23</string>
|
||||
<string>24</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,17 @@ import Foundation
|
|||
import SwiftyUserDefaults
|
||||
|
||||
extension PasswordEntity {
|
||||
|
||||
var nameWithCategory: String {
|
||||
get {
|
||||
if let p = path, p.hasSuffix(".gpg") {
|
||||
return p.substring(to: p.index(p.endIndex, offsetBy: -4))
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func decrypt(passphrase: String) throws -> Password? {
|
||||
var password: Password?
|
||||
let encryptedDataPath = URL(fileURLWithPath: "\(Globals.repositoryPath)/\(path!)")
|
||||
|
|
@ -27,4 +38,15 @@ extension PasswordEntity {
|
|||
let encryptedData = try pgp.encryptData(plainData, usingPublicKey: pgp.getKeysOf(.public)[0], armored: false)
|
||||
return encryptedData
|
||||
}
|
||||
|
||||
func getCategoryText() -> String {
|
||||
var parentEntity = parent
|
||||
var passwordCategoryArray: [String] = []
|
||||
while parentEntity != nil {
|
||||
passwordCategoryArray.append(parentEntity!.name!)
|
||||
parentEntity = parentEntity!.parent
|
||||
}
|
||||
passwordCategoryArray.reverse()
|
||||
return passwordCategoryArray.joined(separator: " > ")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,11 @@ class PasswordStore {
|
|||
let tempStoreURL = URL(fileURLWithPath: "\(Globals.repositoryPath)-temp")
|
||||
var storeRepository: GTRepository?
|
||||
var gitCredential: GitCredential?
|
||||
var gitSignatureForNow: GTSignature {
|
||||
get {
|
||||
return GTSignature(name: Defaults[.gitRepositoryUsername]!, email: Defaults[.gitRepositoryUsername]!+"@passforios", time: Date())!
|
||||
}
|
||||
}
|
||||
|
||||
let pgp: ObjectivePGP = ObjectivePGP()
|
||||
|
||||
|
|
@ -415,50 +420,18 @@ class PasswordStore {
|
|||
func updateRemoteRepo() {
|
||||
}
|
||||
|
||||
|
||||
func addEntryToGTTree(fileData: Data, filename: String) -> GTTree {
|
||||
do {
|
||||
let head = try storeRepository!.headReference()
|
||||
let branch = GTBranch(reference: head, repository: storeRepository!)
|
||||
let headCommit = try branch?.targetCommit()
|
||||
|
||||
let treeBulider = try GTTreeBuilder(tree: headCommit?.tree, repository: storeRepository!)
|
||||
try treeBulider.addEntry(with: fileData, fileName: filename, fileMode: GTFileMode.blob)
|
||||
|
||||
let newTree = try treeBulider.writeTree()
|
||||
return newTree
|
||||
} catch {
|
||||
fatalError("Failed to add entries to GTTree: \(error)")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func removeEntryFromGTTree(filename: String) -> GTTree {
|
||||
do {
|
||||
let head = try storeRepository!.headReference()
|
||||
let branch = GTBranch(reference: head, repository: storeRepository!)
|
||||
let headCommit = try branch?.targetCommit()
|
||||
|
||||
let treeBulider = try GTTreeBuilder(tree: headCommit?.tree, repository: storeRepository!)
|
||||
try treeBulider.removeEntry(withFileName: filename)
|
||||
|
||||
let newTree = try treeBulider.writeTree()
|
||||
return newTree
|
||||
} catch {
|
||||
fatalError("Failed to remove entries to GTTree: \(error)")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func createAddCommitInRepository(message: String, fileData: Data, filename: String, progressBlock: (_ progress: Float) -> Void) -> GTCommit? {
|
||||
do {
|
||||
let newTree = addEntryToGTTree(fileData: fileData, filename: filename)
|
||||
try storeRepository?.index().add(fileData, withPath: filename)
|
||||
try storeRepository?.index().write()
|
||||
let newTree = try storeRepository!.index().writeTree()
|
||||
let headReference = try storeRepository!.headReference()
|
||||
let commitEnum = try GTEnumerator(repository: storeRepository!)
|
||||
try commitEnum.pushSHA(headReference.targetOID.sha!)
|
||||
let parent = commitEnum.nextObject() as! GTCommit
|
||||
progressBlock(0.5)
|
||||
let commit = try storeRepository!.createCommit(with: newTree, message: message, parents: [parent], updatingReferenceNamed: headReference.name)
|
||||
let signature = gitSignatureForNow
|
||||
let commit = try storeRepository!.createCommit(with: newTree, message: message, author: signature, committer: signature, parents: [parent], updatingReferenceNamed: headReference.name)
|
||||
progressBlock(0.7)
|
||||
return commit
|
||||
} catch {
|
||||
|
|
@ -469,13 +442,16 @@ class PasswordStore {
|
|||
|
||||
func createRemoveCommitInRepository(message: String, filename: String, progressBlock: (_ progress: Float) -> Void) -> GTCommit? {
|
||||
do {
|
||||
let newTree = removeEntryFromGTTree(filename: filename)
|
||||
try storeRepository?.index().removeFile(filename)
|
||||
try storeRepository?.index().write()
|
||||
let newTree = try storeRepository!.index().writeTree()
|
||||
let headReference = try storeRepository!.headReference()
|
||||
let commitEnum = try GTEnumerator(repository: storeRepository!)
|
||||
try commitEnum.pushSHA(headReference.targetOID.sha!)
|
||||
let parent = commitEnum.nextObject() as! GTCommit
|
||||
progressBlock(0.5)
|
||||
let commit = try storeRepository!.createCommit(with: newTree, message: message, parents: [parent], updatingReferenceNamed: headReference.name)
|
||||
let signature = gitSignatureForNow
|
||||
let commit = try storeRepository!.createCommit(with: newTree, message: message, author: signature, committer: signature, parents: [parent], updatingReferenceNamed: headReference.name)
|
||||
progressBlock(0.7)
|
||||
return commit
|
||||
} catch {
|
||||
|
|
@ -524,7 +500,7 @@ class PasswordStore {
|
|||
passwordEntity.isDir = false
|
||||
try context.save()
|
||||
print(saveURL.path)
|
||||
let _ = createAddCommitInRepository(message: "Add new password by pass for iOS", fileData: encryptedData, filename: saveURL.lastPathComponent, progressBlock: progressBlock)
|
||||
let _ = createAddCommitInRepository(message: "Add password for \(passwordEntity.nameWithCategory) to store using Pass for iOS.", fileData: encryptedData, filename: saveURL.lastPathComponent, progressBlock: progressBlock)
|
||||
progressBlock(1.0)
|
||||
} catch {
|
||||
print(error)
|
||||
|
|
@ -537,7 +513,7 @@ class PasswordStore {
|
|||
let saveURL = storeURL.appendingPathComponent(passwordEntity.path!)
|
||||
try encryptedData.write(to: saveURL)
|
||||
progressBlock(0.3)
|
||||
let _ = createAddCommitInRepository(message: "Update password by pass for iOS", fileData: encryptedData, filename: saveURL.lastPathComponent, progressBlock: progressBlock)
|
||||
let _ = createAddCommitInRepository(message: "Edit password for \(passwordEntity.nameWithCategory) using Pass for iOS.", fileData: encryptedData, filename: saveURL.lastPathComponent, progressBlock: progressBlock)
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="320" height="89"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="k0U-2N-YaX">
|
||||
<rect key="frame" x="15" y="8" width="297" height="73.5"/>
|
||||
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="password" textAlignment="natural" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="k0U-2N-YaX">
|
||||
<rect key="frame" x="15" y="8" width="220" height="74"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="38" id="qVX-ui-dIn"/>
|
||||
</constraints>
|
||||
|
|
@ -29,7 +29,10 @@
|
|||
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="alphabet"/>
|
||||
</textField>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" reversesTitleShadowWhenHighlighted="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hTh-ek-Xam">
|
||||
<rect key="frame" x="243" y="1" width="64" height="89.5"/>
|
||||
<rect key="frame" x="243" y="-0.5" width="64" height="89.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="64" id="X1A-kc-qJy"/>
|
||||
</constraints>
|
||||
<state key="normal" title="Generate"/>
|
||||
<connections>
|
||||
<action selector="generatePassword:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="M61-hs-PCP"/>
|
||||
|
|
@ -37,13 +40,13 @@
|
|||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="k0U-2N-YaX" secondAttribute="trailing" id="3S1-gj-XVP"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="k0U-2N-YaX" secondAttribute="trailing" constant="77" id="3S1-gj-XVP" userLabel="trailingMargin = Content Text Field.trailing + 71"/>
|
||||
<constraint firstItem="hTh-ek-Xam" firstAttribute="centerY" secondItem="k0U-2N-YaX" secondAttribute="centerY" id="Fls-do-khd"/>
|
||||
<constraint firstItem="hTh-ek-Xam" firstAttribute="height" secondItem="H2p-sc-9uM" secondAttribute="height" id="Gok-dX-tQ5"/>
|
||||
<constraint firstItem="hTh-ek-Xam" firstAttribute="leading" secondItem="k0U-2N-YaX" secondAttribute="trailing" constant="-69" id="hsy-gb-ero"/>
|
||||
<constraint firstItem="hTh-ek-Xam" firstAttribute="leading" secondItem="k0U-2N-YaX" secondAttribute="trailing" constant="8" id="hsy-gb-ero" userLabel="Generate.leading = Content Text Field.trailing"/>
|
||||
<constraint firstItem="k0U-2N-YaX" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="jKd-Xa-tr5"/>
|
||||
<constraint firstItem="k0U-2N-YaX" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" constant="7" id="lAm-D6-pir"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="k0U-2N-YaX" secondAttribute="bottom" id="pLC-H7-JTU"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="k0U-2N-YaX" secondAttribute="bottom" constant="-1" id="pLC-H7-JTU" userLabel="bottomMargin = Content Text Field.bottom"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
|
|
|
|||
27
pass/Views/PasswordWithFolderTableViewCell.swift
Normal file
27
pass/Views/PasswordWithFolderTableViewCell.swift
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// PasswordTableViewCell.swift
|
||||
// pass
|
||||
//
|
||||
// Created by Mingshen Sun on 8/3/2017.
|
||||
// Copyright © 2017 Bob Sun. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class PasswordWithFolderTableViewCell: UITableViewCell {
|
||||
|
||||
@IBOutlet weak var passwordLabel: UILabel!
|
||||
@IBOutlet weak var folderLabel: UILabel!
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
// Initialization code
|
||||
}
|
||||
|
||||
override func setSelected(_ selected: Bool, animated: Bool) {
|
||||
super.setSelected(selected, animated: animated)
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
}
|
||||
52
pass/Views/PasswordWithFolderTableViewCell.xib
Normal file
52
pass/Views/PasswordWithFolderTableViewCell.xib
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12106.1" systemVersion="16E183b" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12074.1"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="passwordWithFolderTableViewCell" rowHeight="43" id="KGk-i7-Jjw" customClass="PasswordWithFolderTableViewCell" customModule="pass" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="42.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Password Entry" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="y5A-3S-tcq">
|
||||
<rect key="frame" x="15" y="8" width="297" height="26.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Family > Parents" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GEv-Cf-Cnx">
|
||||
<rect key="frame" x="8" y="12.5" width="297" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<color key="textColor" red="0.5568627451" green="0.5568627451" blue="0.57647058819999997" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="y5A-3S-tcq" firstAttribute="centerY" secondItem="GEv-Cf-Cnx" secondAttribute="centerY" id="Ev0-0v-v1c"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="GEv-Cf-Cnx" secondAttribute="trailing" constant="7" id="Hyk-Q8-5uU"/>
|
||||
<constraint firstItem="y5A-3S-tcq" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" constant="7" id="VDn-B1-Tyg"/>
|
||||
<constraint firstItem="y5A-3S-tcq" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="e9F-C0-yGP"/>
|
||||
<constraint firstAttribute="bottomMargin" secondItem="y5A-3S-tcq" secondAttribute="bottom" id="f52-hU-sEC"/>
|
||||
<constraint firstAttribute="leadingMargin" secondItem="GEv-Cf-Cnx" secondAttribute="leading" id="rjm-bp-jT3"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="y5A-3S-tcq" secondAttribute="trailing" id="vsW-4d-EEl"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="folderLabel" destination="GEv-Cf-Cnx" id="HHd-LU-wYW"/>
|
||||
<outlet property="passwordLabel" destination="y5A-3S-tcq" id="1OK-Io-6mP"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="34" y="53.5"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
Loading…
Add table
Add a link
Reference in a new issue