From 7ee82f5e55f964823fe2f93b016e0dee2dce57ab Mon Sep 17 00:00:00 2001 From: Joscha <joscha@virtual-artz.de> Date: Fri, 4 Aug 2017 12:56:04 +0200 Subject: [PATCH] Generate QR code for own public key fingerprint, shown in own tray; added QR code scanner with fingerprint verification; verification status update not working jet --- enzevalos_iphone.xcodeproj/project.pbxproj | 30 ++- enzevalos_iphone/Base.lproj/Main.storyboard | 193 ++++++++++++++---- enzevalos_iphone/ContactViewController.swift | 57 ++++-- enzevalos_iphone/CustomCells.swift | 5 + enzevalos_iphone/Info.plist | 38 ++-- enzevalos_iphone/QRCodeGenerator.swift | 27 +++ enzevalos_iphone/QRScannerView.swift | 152 ++++++++++++++ enzevalos_iphone/ViewControllerPannable.swift | 55 +++++ enzevalos_iphone/de.lproj/Localizable.strings | 8 +- enzevalos_iphone/en.lproj/Localizable.strings | 6 + 10 files changed, 497 insertions(+), 74 deletions(-) create mode 100644 enzevalos_iphone/QRCodeGenerator.swift create mode 100644 enzevalos_iphone/QRScannerView.swift create mode 100644 enzevalos_iphone/ViewControllerPannable.swift diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj index efd32e0b..07334eb8 100644 --- a/enzevalos_iphone.xcodeproj/project.pbxproj +++ b/enzevalos_iphone.xcodeproj/project.pbxproj @@ -147,11 +147,14 @@ A1F992291DA7C9100073BF1B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A1F9922B1DA7C9100073BF1B /* Main.storyboard */; }; A1F992391DA7DD2E0073BF1B /* InboxTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A1F9923B1DA7DD2E0073BF1B /* InboxTableViewCell.xib */; }; A1FA3F6C1E78565B0093C0B6 /* alice2005-public.gpg in Resources */ = {isa = PBXBuildFile; fileRef = A1FA3F6B1E78565B0093C0B6 /* alice2005-public.gpg */; }; + F113C3851F30D06800E7F1D6 /* QRScannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F113C3841F30D06800E7F1D6 /* QRScannerView.swift */; }; + F113C38B1F3344C200E7F1D6 /* ViewControllerPannable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F113C38A1F3344C200E7F1D6 /* ViewControllerPannable.swift */; }; F119D2901E364B59001D732A /* AnimatedSendIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F119D28F1E364B59001D732A /* AnimatedSendIcon.swift */; }; F12041FB1DA3FBF7002E4940 /* ListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12041FA1DA3FBF7002E4940 /* ListViewController.swift */; }; F12041FD1DA409A5002E4940 /* ListViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12041FC1DA409A5002E4940 /* ListViewCell.swift */; }; F12060801DA540FE00F6EF37 /* RefreshControlExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F120607F1DA540FE00F6EF37 /* RefreshControlExtension.swift */; }; F12060821DA552FC00F6EF37 /* MailHandlerDelegator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F12060811DA552FC00F6EF37 /* MailHandlerDelegator.swift */; }; + F14239C11F30A99C00998A83 /* QRCodeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F14239C01F30A99C00998A83 /* QRCodeGenerator.swift */; }; F14D189C1ED880680080515D /* nchr-private.gpg in Resources */ = {isa = PBXBuildFile; fileRef = F14D18981ED880680080515D /* nchr-private.gpg */; }; F14D189D1ED880680080515D /* nchr-public.gpg in Resources */ = {isa = PBXBuildFile; fileRef = F14D18991ED880680080515D /* nchr-public.gpg */; }; F14D189E1ED880680080515D /* ncpayroll-private.gpg in Resources */ = {isa = PBXBuildFile; fileRef = F14D189A1ED880680080515D /* ncpayroll-private.gpg */; }; @@ -414,11 +417,14 @@ AE7C40F081DAC9A0A130BE21 /* Pods-enzevalos_iphone.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphone.debug.xcconfig"; path = "../workspace/Pods/Target Support Files/Pods-enzevalos_iphone/Pods-enzevalos_iphone.debug.xcconfig"; sourceTree = "<group>"; }; C7733DFEFB7E7CFF38EC1665 /* Pods-enzevalos_iphoneTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-enzevalos_iphoneTests.release.xcconfig"; path = "../workspace/Pods/Target Support Files/Pods-enzevalos_iphoneTests/Pods-enzevalos_iphoneTests.release.xcconfig"; sourceTree = "<group>"; }; C9B9CE43043CF806E1C02FCA /* Pods_enzevalos_iphoneTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_enzevalos_iphoneTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F113C3841F30D06800E7F1D6 /* QRScannerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRScannerView.swift; sourceTree = "<group>"; }; + F113C38A1F3344C200E7F1D6 /* ViewControllerPannable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllerPannable.swift; sourceTree = "<group>"; }; F119D28F1E364B59001D732A /* AnimatedSendIcon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatedSendIcon.swift; sourceTree = "<group>"; }; F12041FA1DA3FBF7002E4940 /* ListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListViewController.swift; sourceTree = "<group>"; }; F12041FC1DA409A5002E4940 /* ListViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListViewCell.swift; sourceTree = "<group>"; }; F120607F1DA540FE00F6EF37 /* RefreshControlExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshControlExtension.swift; sourceTree = "<group>"; }; F12060811DA552FC00F6EF37 /* MailHandlerDelegator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MailHandlerDelegator.swift; sourceTree = "<group>"; }; + F14239C01F30A99C00998A83 /* QRCodeGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRCodeGenerator.swift; sourceTree = "<group>"; }; F14D18981ED880680080515D /* nchr-private.gpg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "nchr-private.gpg"; path = "keys/nchr-private.gpg"; sourceTree = "<group>"; }; F14D18991ED880680080515D /* nchr-public.gpg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "nchr-public.gpg"; path = "keys/nchr-public.gpg"; sourceTree = "<group>"; }; F14D189A1ED880680080515D /* ncpayroll-private.gpg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "ncpayroll-private.gpg"; path = "keys/ncpayroll-private.gpg"; sourceTree = "<group>"; }; @@ -667,6 +673,7 @@ F1ACF21D1E0C290500C1B843 /* contactView */, A1D5076D1E80254D00B68B38 /* keyView */, A13526781D955BDF00D3BFE1 /* AppDelegate.swift */, + F113C3831F30D01A00E7F1D6 /* QRCode */, 476142071E07E52B00FD5E4F /* Theme.swift */, A1230BD81E2F881E006642C7 /* Encryption */, A1EB059B1D956957008659C1 /* NSDateCompare.swift */, @@ -870,6 +877,16 @@ name = read; sourceTree = "<group>"; }; + F113C3831F30D01A00E7F1D6 /* QRCode */ = { + isa = PBXGroup; + children = ( + F113C3841F30D06800E7F1D6 /* QRScannerView.swift */, + F113C38A1F3344C200E7F1D6 /* ViewControllerPannable.swift */, + F14239C01F30A99C00998A83 /* QRCodeGenerator.swift */, + ); + name = QRCode; + sourceTree = "<group>"; + }; F1ACF21D1E0C290500C1B843 /* contactView */ = { isa = PBXGroup; children = ( @@ -961,7 +978,7 @@ TargetAttributes = { A13526741D955BDF00D3BFE1 = { CreatedOnToolsVersion = 7.3.1; - DevelopmentTeam = VJ9C93G68Y; + DevelopmentTeam = 4377G946WP; LastSwiftMigration = 0820; ProvisioningStyle = Automatic; SystemCapabilities = { @@ -1232,6 +1249,7 @@ A135CF221DD4BDD1007E3C29 /* PGPUser.m in Sources */, A135CF031DD4BDD1007E3C29 /* NSData+PGPUtils.m in Sources */, 472F398C1E2519C8009260FB /* CNContactExtension.swift in Sources */, + F113C3851F30D06800E7F1D6 /* QRScannerView.swift in Sources */, A135CF171DD4BDD1007E3C29 /* PGPPublicKeyRSA.m in Sources */, F18B44601E704C550080C041 /* ReplaceSegue.swift in Sources */, A135CF181DD4BDD1007E3C29 /* PGPPublicSubKeyPacket.m in Sources */, @@ -1248,6 +1266,7 @@ 4781753D1F06E57E00300D20 /* compress.c in Sources */, A1E81B671DCA296200535F98 /* UIViewResolver.swift in Sources */, A135CF0F1DD4BDD1007E3C29 /* PGPMPI.m in Sources */, + F14239C11F30A99C00998A83 /* QRCodeGenerator.swift in Sources */, 472F392A1E1277D2009260FB /* EnzevalosContact+CoreDataClass.swift in Sources */, F1AF938F1E2D04BA00755128 /* CustomCells.swift in Sources */, A135CF191DD4BDD1007E3C29 /* PGPS2K.m in Sources */, @@ -1287,6 +1306,7 @@ 478175451F06E57E00300D20 /* netpgp.c in Sources */, A135CF081DD4BDD1007E3C29 /* PGPCryptoCFB.m in Sources */, A1416C1B1E268F1A001809F3 /* Encryption.swift in Sources */, + F113C38B1F3344C200E7F1D6 /* ViewControllerPannable.swift in Sources */, A1EB05841D956867008659C1 /* TableViewDataDelegate.swift in Sources */, 4781753E1F06E57E00300D20 /* create.c in Sources */, A15B7BE41E29306D0024E499 /* EnzevalosEncryptionHandler.swift in Sources */, @@ -1520,7 +1540,7 @@ CODE_SIGN_ENTITLEMENTS = enzevalos_iphone/enzevalos_iphone.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer: bushman@gmx.net (UQMSUAQE2Q)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = VJ9C93G68Y; + DEVELOPMENT_TEAM = 4377G946WP; INFOPLIST_FILE = enzevalos_iphone/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1547,7 +1567,7 @@ "-framework", "\"VENTokenField\"", ); - PRODUCT_BUNDLE_IDENTIFIER = "fu-berlin.enzevalos-iphone"; + PRODUCT_BUNDLE_IDENTIFIER = "fu-berlin.enzevalos"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1569,7 +1589,7 @@ CODE_SIGN_ENTITLEMENTS = enzevalos_iphone/enzevalos_iphone.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer: bushman@gmx.net (UQMSUAQE2Q)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = VJ9C93G68Y; + DEVELOPMENT_TEAM = 4377G946WP; INFOPLIST_FILE = enzevalos_iphone/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1596,7 +1616,7 @@ "-framework", "\"VENTokenField\"", ); - PRODUCT_BUNDLE_IDENTIFIER = "fu-berlin.enzevalos-iphone"; + PRODUCT_BUNDLE_IDENTIFIER = "fu-berlin.enzevalos"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/enzevalos_iphone/Base.lproj/Main.storyboard b/enzevalos_iphone/Base.lproj/Main.storyboard index 5587c41a..63529ae7 100644 --- a/enzevalos_iphone/Base.lproj/Main.storyboard +++ b/enzevalos_iphone/Base.lproj/Main.storyboard @@ -6,6 +6,7 @@ <dependencies> <deployment identifier="iOS"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/> + <capability name="Aspect ratio constraints" minToolsVersion="5.1"/> <capability name="Constraints to layout margins" minToolsVersion="6.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> @@ -249,7 +250,7 @@ <rect key="frame" x="0.0" y="0.0" width="375" height="44"/> <autoresizingMask key="autoresizingMask"/> <subviews> - <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" bouncesZoom="NO" editable="NO" textAlignment="natural" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oLv-OU-RRD"> + <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" bouncesZoom="NO" editable="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="oLv-OU-RRD"> <rect key="frame" x="8" y="12" width="359" height="32"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <fontDescription key="fontDescription" type="system" pointSize="16"/> @@ -361,7 +362,7 @@ </navigationController> <placeholder placeholderIdentifier="IBFirstResponder" id="bg6-Th-yQH" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="-483" y="-296"/> + <point key="canvasLocation" x="-705" y="-296"/> </scene> <!--Navigation Controller--> <scene sceneID="z9j-Pi-N8o"> @@ -377,7 +378,7 @@ </navigationController> <placeholder placeholderIdentifier="IBFirstResponder" id="ivB-W5-lhL" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="-830" y="-948"/> + <point key="canvasLocation" x="-1457" y="-1129"/> </scene> <!--Onboarding View Controller--> <scene sceneID="XIS-Im-ruJ"> @@ -463,7 +464,7 @@ </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="B3N-gi-asB" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="-31.199999999999999" y="-949.47526236881572"/> + <point key="canvasLocation" x="-708" y="-1129"/> </scene> <!--Inbox--> <scene sceneID="ue1-yd-fJq"> @@ -506,7 +507,7 @@ </tableViewController> <placeholder placeholderIdentifier="IBFirstResponder" id="EUm-6R-021" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="211" y="-296"/> + <point key="canvasLocation" x="132" y="-298"/> </scene> <!--List View Controller--> <scene sceneID="nHr-nr-mUZ"> @@ -592,7 +593,7 @@ </tableViewController> <placeholder placeholderIdentifier="IBFirstResponder" id="eGM-5k-oNk" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="210" y="432"/> + <point key="canvasLocation" x="130" y="430"/> </scene> <!--Contact View Controller--> <scene sceneID="6er-JI-0Op"> @@ -603,11 +604,11 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/> <prototypes> - <tableViewCell clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="ContactViewCell" rowHeight="88" id="92W-gl-tvY" customClass="ContactViewCell" customModule="enzevalos_iphone" customModuleProvider="target"> - <rect key="frame" x="0.0" y="55.5" width="375" height="88"/> + <tableViewCell clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="ContactViewCell" id="92W-gl-tvY" customClass="ContactViewCell" customModule="enzevalos_iphone" customModuleProvider="target"> + <rect key="frame" x="0.0" y="56" width="375" height="44"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="92W-gl-tvY" id="x9d-DW-WTy"> - <rect key="frame" x="0.0" y="0.0" width="375" height="87"/> + <rect key="frame" x="0.0" y="0.0" width="375" height="43"/> <autoresizingMask key="autoresizingMask"/> <subviews> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="8Bg-PX-E3I"> @@ -618,7 +619,7 @@ </constraints> </imageView> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Kontakt ist noch nicht verifiziert" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lXU-0n-bPI"> - <rect key="frame" x="86" y="23" width="203" height="41"/> + <rect key="frame" x="86" y="23.5" width="203" height="41"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <nil key="textColor"/> <nil key="highlightedColor"/> @@ -652,15 +653,15 @@ <outlet property="iconImage" destination="Rho-9E-ThM" id="FKW-4n-0Yk"/> </connections> </tableViewCell> - <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="ActionCell" id="yRi-ET-5KB" customClass="ActionCell" customModule="enzevalos_iphone" customModuleProvider="target"> - <rect key="frame" x="0.0" y="143.5" width="375" height="44"/> + <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="ActionCell" id="yRi-ET-5KB" customClass="ActionCell" customModule="enzevalos_iphone" customModuleProvider="target"> + <rect key="frame" x="0.0" y="100" width="375" height="44"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="yRi-ET-5KB" id="zZH-rZ-dKr"> <rect key="frame" x="0.0" y="0.0" width="375" height="43"/> <autoresizingMask key="autoresizingMask"/> <subviews> <button opaque="NO" tag="1" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tex-hl-7Hg" userLabel="Button"> - <rect key="frame" x="8" y="5" width="359" height="33"/> + <rect key="frame" x="0.0" y="5" width="375" height="33"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/> <state key="normal" title="Jetzt verifizieren"/> <connections> @@ -671,8 +672,8 @@ <constraints> <constraint firstItem="tex-hl-7Hg" firstAttribute="centerY" secondItem="zZH-rZ-dKr" secondAttribute="centerY" id="0R9-4g-WDZ"/> <constraint firstItem="tex-hl-7Hg" firstAttribute="centerX" secondItem="zZH-rZ-dKr" secondAttribute="centerX" id="JIw-wV-yNx"/> - <constraint firstItem="tex-hl-7Hg" firstAttribute="leading" secondItem="zZH-rZ-dKr" secondAttribute="leadingMargin" id="e75-f6-zgh"/> - <constraint firstAttribute="trailingMargin" secondItem="tex-hl-7Hg" secondAttribute="trailing" id="iRV-hN-6UQ"/> + <constraint firstItem="tex-hl-7Hg" firstAttribute="leading" secondItem="zZH-rZ-dKr" secondAttribute="leading" id="e75-f6-zgh"/> + <constraint firstAttribute="trailing" secondItem="tex-hl-7Hg" secondAttribute="trailing" id="iRV-hN-6UQ"/> </constraints> </tableViewCellContentView> <inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/> @@ -680,8 +681,46 @@ <outlet property="Button" destination="tex-hl-7Hg" id="FMr-CY-5Zg"/> </connections> </tableViewCell> + <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="QRCodeCell" rowHeight="250" id="nKx-D5-RbU" customClass="QRCodeCell" customModule="enzevalos_iphone" customModuleProvider="target"> + <rect key="frame" x="0.0" y="144" width="375" height="250"/> + <autoresizingMask key="autoresizingMask"/> + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nKx-D5-RbU" id="Gve-IO-FHr"> + <rect key="frame" x="0.0" y="0.0" width="375" height="249"/> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="Q4B-Fx-kK0"> + <rect key="frame" x="87.5" y="8" width="200" height="233.5"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Dein Fingerabdruck:" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VXS-xJ-eqF"> + <rect key="frame" x="23" y="0.0" width="154.5" height="33.5"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="fpa-sz-ZpT"> + <rect key="frame" x="0.0" y="33.5" width="200" height="200"/> + <constraints> + <constraint firstAttribute="width" secondItem="fpa-sz-ZpT" secondAttribute="height" multiplier="1:1" id="3zZ-yQ-2zX"/> + <constraint firstAttribute="width" constant="200" id="7mN-Ad-OqE"/> + <constraint firstAttribute="height" constant="200" id="mCX-KQ-Shl"/> + </constraints> + </imageView> + </subviews> + </stackView> + </subviews> + <constraints> + <constraint firstItem="Q4B-Fx-kK0" firstAttribute="centerX" secondItem="Gve-IO-FHr" secondAttribute="centerX" id="dP6-Xj-G93"/> + <constraint firstItem="Q4B-Fx-kK0" firstAttribute="top" secondItem="Gve-IO-FHr" secondAttribute="topMargin" id="gn6-az-QnS"/> + <constraint firstAttribute="bottomMargin" secondItem="Q4B-Fx-kK0" secondAttribute="bottom" id="hj7-Ff-yBm"/> + </constraints> + </tableViewCellContentView> + <connections> + <outlet property="label" destination="VXS-xJ-eqF" id="7z4-78-uEm"/> + <outlet property="qrCode" destination="fpa-sz-ZpT" id="YfY-Ti-PAQ"/> + </connections> + </tableViewCell> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="MailCell" rowHeight="64" id="8qd-Go-Jup" customClass="MailCell" customModule="enzevalos_iphone" customModuleProvider="target"> - <rect key="frame" x="0.0" y="187.5" width="375" height="64"/> + <rect key="frame" x="0.0" y="394" width="375" height="64"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="8qd-Go-Jup" id="CEB-dH-z8s"> <rect key="frame" x="0.0" y="0.0" width="375" height="63"/> @@ -715,14 +754,14 @@ </connections> </tableViewCell> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="AllMails" textLabel="VTZ-4w-fot" style="IBUITableViewCellStyleDefault" id="dM9-jb-EcN"> - <rect key="frame" x="0.0" y="251.5" width="375" height="44"/> + <rect key="frame" x="0.0" y="458" width="375" height="44"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="dM9-jb-EcN" id="tvN-re-z1Z"> - <rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/> + <rect key="frame" x="0.0" y="0.0" width="342" 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="VTZ-4w-fot"> - <rect key="frame" x="16" y="0.0" width="324" height="43.5"/> + <rect key="frame" x="15" y="0.0" width="325" height="43.5"/> <autoresizingMask key="autoresizingMask"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <nil key="textColor"/> @@ -735,7 +774,7 @@ </connections> </tableViewCell> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="KeyCell" id="Lke-0s-P0i" userLabel="KeyCell"> - <rect key="frame" x="0.0" y="295.5" width="375" height="44"/> + <rect key="frame" x="0.0" y="502" width="375" height="44"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Lke-0s-P0i" id="QYX-AX-hbo"> <rect key="frame" x="0.0" y="0.0" width="342" height="43"/> @@ -746,7 +785,7 @@ </connections> </tableViewCell> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="RecordCell" id="hTc-vs-AIl" customClass="RecordCell" customModule="enzevalos_iphone" customModuleProvider="target"> - <rect key="frame" x="0.0" y="339.5" width="375" height="44"/> + <rect key="frame" x="0.0" y="546" width="375" height="44"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="hTc-vs-AIl" id="pJ9-4e-7at"> <rect key="frame" x="0.0" y="0.0" width="342" height="43"/> @@ -794,8 +833,10 @@ </prototypes> <sections/> </tableView> + <nil key="simulatedBottomBarMetrics"/> <connections> <outlet property="tableView" destination="lK7-ug-OyQ" id="huh-IM-Frk"/> + <segue destination="86r-Nd-UBB" kind="presentation" identifier="verifyQRCode" modalPresentationStyle="overCurrentContext" id="dJq-ky-We8"/> </connections> </tableViewController> <placeholder placeholderIdentifier="IBFirstResponder" id="9aV-lm-D5U" userLabel="First Responder" sceneMemberID="firstResponder"/> @@ -829,7 +870,7 @@ <autoresizingMask key="autoresizingMask"/> <subviews> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Z5E-3a-5Ef"> - <rect key="frame" x="16" y="12" width="33.5" height="20.5"/> + <rect key="frame" x="15" y="12" width="33.5" height="20.5"/> <autoresizingMask key="autoresizingMask"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <nil key="textColor"/> @@ -853,7 +894,7 @@ <autoresizingMask key="autoresizingMask"/> <subviews> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="MR1-qA-5h4"> - <rect key="frame" x="16" y="12" width="33.5" height="20.5"/> + <rect key="frame" x="15" y="12" width="33.5" height="20.5"/> <autoresizingMask key="autoresizingMask"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <nil key="textColor"/> @@ -877,7 +918,7 @@ <autoresizingMask key="autoresizingMask"/> <subviews> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="xLe-fn-BGo"> - <rect key="frame" x="16" y="12" width="33.5" height="20.5"/> + <rect key="frame" x="15" y="12" width="33.5" height="20.5"/> <autoresizingMask key="autoresizingMask"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <nil key="textColor"/> @@ -901,7 +942,7 @@ <autoresizingMask key="autoresizingMask"/> <subviews> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="SsF-tc-fh9"> - <rect key="frame" x="16" y="12" width="33.5" height="20.5"/> + <rect key="frame" x="15" y="12" width="33.5" height="20.5"/> <autoresizingMask key="autoresizingMask"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <nil key="textColor"/> @@ -925,7 +966,7 @@ <autoresizingMask key="autoresizingMask"/> <subviews> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="xHD-7H-RVy"> - <rect key="frame" x="16" y="12" width="33.5" height="20.5"/> + <rect key="frame" x="15" y="12" width="33.5" height="20.5"/> <autoresizingMask key="autoresizingMask"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <nil key="textColor"/> @@ -973,7 +1014,87 @@ </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="d2t-44-qYZ" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="1813.5999999999999" y="429.53523238380814"/> + <point key="canvasLocation" x="1710" y="430"/> + </scene> + <!--Scanner View--> + <scene sceneID="ey5-iR-K6K"> + <objects> + <viewController id="86r-Nd-UBB" customClass="QRScannerView" customModule="enzevalos_iphone" customModuleProvider="target" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="q5b-fS-r0h"/> + <viewControllerLayoutGuide type="bottom" id="l8F-2c-Ili"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="sqq-s3-zif"> + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nMw-DD-7LP" userLabel="TopBar"> + <rect key="frame" x="0.0" y="0.0" width="375" height="55"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Kontakt verifizieren" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="25l-XT-PFo"> + <rect key="frame" x="94" y="22" width="188" height="26.5"/> + <fontDescription key="fontDescription" style="UICTFontTextStyleTitle2"/> + <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <nil key="highlightedColor"/> + </label> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="w9U-eC-Koh"> + <rect key="frame" x="8" y="17" width="30" height="38"/> + <fontDescription key="fontDescription" type="system" weight="heavy" pointSize="21"/> + <state key="normal" title="✕"> + <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + </state> + <connections> + <action selector="close:" destination="86r-Nd-UBB" eventType="touchUpInside" id="CLz-tz-tXJ"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstAttribute="height" constant="55" id="34d-AO-n6J"/> + <constraint firstItem="w9U-eC-Koh" firstAttribute="leading" secondItem="nMw-DD-7LP" secondAttribute="leading" constant="8" id="FiC-nk-Xba"/> + <constraint firstItem="25l-XT-PFo" firstAttribute="centerX" secondItem="nMw-DD-7LP" secondAttribute="centerX" id="Hoa-Sw-4C2"/> + <constraint firstItem="25l-XT-PFo" firstAttribute="centerY" secondItem="w9U-eC-Koh" secondAttribute="centerY" constant="-1" id="afo-9z-M44"/> + </constraints> + </view> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ukS-99-lnz" userLabel="BottomBar"> + <rect key="frame" x="0.0" y="617" width="375" height="50"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Scanne den QR Code des Kontaktes" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ysO-xv-18D"> + <rect key="frame" x="49" y="15" width="276.5" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <constraints> + <constraint firstAttribute="height" constant="50" id="HTK-Hd-OQp"/> + <constraint firstItem="ysO-xv-18D" firstAttribute="centerY" secondItem="ukS-99-lnz" secondAttribute="centerY" id="czC-UC-1G4"/> + <constraint firstItem="ysO-xv-18D" firstAttribute="centerX" secondItem="ukS-99-lnz" secondAttribute="centerX" id="t0L-4N-dj8"/> + </constraints> + </view> + </subviews> + <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/> + <gestureRecognizers/> + <constraints> + <constraint firstItem="nMw-DD-7LP" firstAttribute="centerX" secondItem="sqq-s3-zif" secondAttribute="centerX" id="48b-He-7J4"/> + <constraint firstItem="nMw-DD-7LP" firstAttribute="top" secondItem="q5b-fS-r0h" secondAttribute="bottom" constant="-20" id="GRQ-9H-Kbm"/> + <constraint firstItem="nMw-DD-7LP" firstAttribute="leading" secondItem="sqq-s3-zif" secondAttribute="leading" id="TBy-Pe-lVg"/> + <constraint firstItem="ukS-99-lnz" firstAttribute="leading" secondItem="sqq-s3-zif" secondAttribute="leadingMargin" constant="-16" id="mYJ-Xu-94I"/> + <constraint firstAttribute="trailing" secondItem="nMw-DD-7LP" secondAttribute="trailing" id="wX4-Hd-qiJ"/> + <constraint firstItem="w9U-eC-Koh" firstAttribute="top" secondItem="q5b-fS-r0h" secondAttribute="bottom" constant="-3" id="x7c-VW-vac"/> + <constraint firstAttribute="trailingMargin" secondItem="ukS-99-lnz" secondAttribute="trailing" constant="-16" id="xvf-Nw-Eh8"/> + <constraint firstItem="l8F-2c-Ili" firstAttribute="top" secondItem="ukS-99-lnz" secondAttribute="bottom" id="zfM-Ky-ucf"/> + </constraints> + </view> + <connections> + <outlet property="bottomBar" destination="ukS-99-lnz" id="ePV-Zz-Z2T"/> + <outlet property="bottomLabel" destination="ysO-xv-18D" id="l96-Z6-VOj"/> + <outlet property="topBar" destination="nMw-DD-7LP" id="8rY-ed-P10"/> + <outlet property="topLabel" destination="25l-XT-PFo" id="KSW-l2-ftD"/> + </connections> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="9Je-jm-HTL" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="2490" y="428"/> </scene> <!--Send View Controller--> <scene sceneID="gr5-XJ-geZ"> @@ -984,11 +1105,11 @@ <viewControllerLayoutGuide type="bottom" id="zNd-c4-1JB"/> </layoutGuides> <view key="view" contentMode="scaleToFill" id="5dv-YO-2iV"> - <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> + <rect key="frame" x="0.0" y="64" width="375" height="603"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleAspectFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" keyboardDismissMode="interactive" translatesAutoresizingMaskIntoConstraints="NO" id="sij-Oe-ann"> - <rect key="frame" x="1" y="20" width="376" height="585"/> + <rect key="frame" x="1" y="0.0" width="376" height="541"/> <subviews> <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" placeholderIntrinsicWidth="373" placeholderIntrinsicHeight="100" showsVerticalScrollIndicator="NO" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" prefetchingEnabled="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KMI-R1-Q95"> <rect key="frame" x="0.0" y="44" width="373" height="100"/> @@ -1129,7 +1250,7 @@ </connections> </scrollView> <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" dataMode="prototypes" style="plain" separatorStyle="default" sectionIndexMinimumDisplayRowCount="1" rowHeight="70" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="iEa-Rh-6bS"> - <rect key="frame" x="-4" y="162" width="383" height="100"/> + <rect key="frame" x="-4" y="142" width="383" height="100"/> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <constraints> <constraint firstAttribute="height" constant="100" id="fcx-4L-TLn"/> @@ -1188,13 +1309,13 @@ </connections> </barButtonItem> <button key="titleView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="iUk-lk-1LN"> - <rect key="frame" x="143" y="-6" width="90" height="56"/> + <rect key="frame" x="142" y="-6" width="90" height="56"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMaxY="YES"/> <connections> <action selector="iconButtonPressed:" destination="4Ey-v4-VeB" eventType="touchUpInside" id="Opj-Y1-Vtg"/> </connections> </button> - <barButtonItem key="rightBarButtonItem" title="Send" style="plain" id="2IZ-1g-KCZ"> + <barButtonItem key="rightBarButtonItem" title="Send" style="done" id="2IZ-1g-KCZ"> <connections> <action selector="pressSend:" destination="4Ey-v4-VeB" id="KOf-wC-7mV"/> </connections> @@ -1307,7 +1428,7 @@ </connections> </tapGestureRecognizer> </objects> - <point key="canvasLocation" x="2382" y="-296"/> + <point key="canvasLocation" x="2490" y="-299"/> </scene> <!--Navigation Controller--> <scene sceneID="Yhz-iC-twy"> @@ -1325,13 +1446,13 @@ </navigationController> <placeholder placeholderIdentifier="IBFirstResponder" id="6lO-b2-keW" userLabel="First Responder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="1624.8" y="-296.40179910044981"/> + <point key="canvasLocation" x="1710" y="-297"/> </scene> </scenes> <inferredMetricsTieBreakers> - <segue reference="rhW-cI-4c4"/> <segue reference="ecN-Wn-7S0"/> <segue reference="D6m-L0-5AB"/> - <segue reference="btx-4o-o0r"/> + <segue reference="kND-73-kqr"/> + <segue reference="3Wb-uL-BB5"/> </inferredMetricsTieBreakers> </document> diff --git a/enzevalos_iphone/ContactViewController.swift b/enzevalos_iphone/ContactViewController.swift index ac850875..223e4c2b 100644 --- a/enzevalos_iphone/ContactViewController.swift +++ b/enzevalos_iphone/ContactViewController.swift @@ -36,7 +36,7 @@ class ContactViewController: UIViewController { self.navigationController?.navigationBar.barTintColor = ThemeManager.defaultColor if let con = keyRecord { hasKey = EnzevalosEncryptionHandler.hasKey(con.ezContact) - + let myAddress = UserManager.loadUserValue(Attribute.userAddr) as! String if con.addresses.contains(where: { $0.mailAddress.lowercased() == myAddress }) { @@ -142,13 +142,19 @@ class ContactViewController: UIViewController { } @IBAction func actionButton(_ sender: AnyObject) { - if (sender as? UIButton)?.titleLabel?.text == NSLocalizedString("toEncrypted", comment: "switch to encrypted") { + guard let sender = sender as? UIButton else { + return + } + + if sender.titleLabel?.text == NSLocalizedString("toEncrypted", comment: "switch to encrypted") { let myPath = IndexPath(row: 1, section: 0) tableView.selectRow(at: myPath, animated: false, scrollPosition: .none) performSegue(withIdentifier: "otherRecord", sender: nil) - } else if (sender as? UIButton)?.titleLabel?.text == NSLocalizedString("invite", comment: "invite contact") { - let mail = EphemeralMail(to: NSSet.init(array: keyRecord!.addresses), cc: NSSet.init(), bcc: NSSet.init(), date: Date(), subject: NSLocalizedString("inviteSubject", comment: ""), body: NSLocalizedString("inviteText", comment: ""), uid: 0,predecessor: nil) + } else if sender.titleLabel?.text == NSLocalizedString("invite", comment: "invite contact") { + let mail = EphemeralMail(to: NSSet.init(array: keyRecord!.addresses), cc: NSSet.init(), bcc: NSSet.init(), date: Date(), subject: NSLocalizedString("inviteSubject", comment: ""), body: NSLocalizedString("inviteText", comment: ""), uid: 0, predecessor: nil) performSegue(withIdentifier: "newMail", sender: mail) + } else if sender.titleLabel?.text == NSLocalizedString("verifyNow", comment: "Verify now") && keyRecord!.key != nil { + performSegue(withIdentifier: "verifyQRCode", sender: EnzevalosEncryptionHandler.getEncryption(.PGP)?.getKey(keyRecord!.key!)?.fingerprint) } } @@ -182,8 +188,18 @@ class ContactViewController: UIViewController { } else if segue.identifier == "keyView" { let destinationViewController: KeyViewController = segue.destination as! KeyViewController destinationViewController.record = keyRecord + } else if segue.identifier == "verifyQRCode" { + if let DestinationViewController = segue.destination as? QRScannerView { + DestinationViewController.fingerprint = EnzevalosEncryptionHandler.getEncryption(.PGP)!.getKey(keyRecord!.key!)!.fingerprint + DestinationViewController.callback = verifySuccessfull + } } } + + func verifySuccessfull() { +// EnzevalosEncryptionHandler.getEncryption(.PGP)!.getKey(keyRecord!.key!)!.verified = true // TODO @Jakob: key is not writable + tableView.reloadData() + } } extension ContactViewController: CNContactViewControllerDelegate { @@ -216,17 +232,30 @@ extension ContactViewController: UITableViewDataSource { } return cell } else if indexPath.row == 1 { - let actionCell = tableView.dequeueReusableCell(withIdentifier: "ActionCell", for: indexPath) as! ActionCell - if keyRecord!.hasKey { - actionCell.Button.setTitle(NSLocalizedString("verifyNow", comment: "Verify now"), for: UIControlState()) - } else if (otherRecords?.filter({ $0.hasKey }).count ?? 0) > 0 { - actionCell.Button.setTitle(NSLocalizedString("toEncrypted", comment: "switch to encrypted"), for: UIControlState()) - } else if hasKey { - actionCell.Button.setTitle(NSLocalizedString("verifyNow", comment: "Verify now"), for: UIControlState()) + if isUser && keyRecord!.hasKey { + let qrCodeCell = tableView.dequeueReusableCell(withIdentifier: "QRCodeCell", for: indexPath) as! QRCodeCell + let qrCode = QRCode.generate(input: "OPENPGP4FPR:\(EnzevalosEncryptionHandler.getEncryption(.PGP)!.getKey(keyRecord!.key!)!.fingerprint)") + + let scaleX = qrCodeCell.qrCode.frame.size.width / qrCode.extent.size.width + let scaleY = qrCodeCell.qrCode.frame.size.height / qrCode.extent.size.height + + qrCodeCell.label.text = NSLocalizedString("yourFingerprint", comment: "") + qrCodeCell.qrCode.image = UIImage(ciImage: qrCode.applying(CGAffineTransform(scaleX: scaleX, y: scaleY))) + + return qrCodeCell } else { - actionCell.Button.setTitle(NSLocalizedString("invite", comment: "Invide contact to use encryption"), for: UIControlState()) + let actionCell = tableView.dequeueReusableCell(withIdentifier: "ActionCell", for: indexPath) as! ActionCell + if keyRecord!.hasKey { + actionCell.Button.setTitle(NSLocalizedString("verifyNow", comment: "Verify now"), for: UIControlState()) + } else if (otherRecords?.filter({ $0.hasKey }).count ?? 0) > 0 { + actionCell.Button.setTitle(NSLocalizedString("toEncrypted", comment: "switch to encrypted"), for: UIControlState()) + } else if hasKey { + actionCell.Button.setTitle(NSLocalizedString("verifyNow", comment: "Verify now"), for: UIControlState()) + } else { + actionCell.Button.setTitle(NSLocalizedString("invite", comment: "Invide contact to use encryption"), for: UIControlState()) + } + return actionCell } - return actionCell } case 1: let cell = tableView.dequeueReusableCell(withIdentifier: "MailCell") as! MailCell @@ -310,7 +339,7 @@ extension ContactViewController: UITableViewDataSource { if let record = keyRecord { switch section { case 0: - if !record.isVerified && !isUser { + if !record.isVerified { return 2 } case 1: diff --git a/enzevalos_iphone/CustomCells.swift b/enzevalos_iphone/CustomCells.swift index 2c2e948a..45b01402 100644 --- a/enzevalos_iphone/CustomCells.swift +++ b/enzevalos_iphone/CustomCells.swift @@ -29,3 +29,8 @@ class RecordCell: UITableViewCell { @IBOutlet weak var label: UILabel! @IBOutlet weak var dateLabel: UILabel! } + +class QRCodeCell: UITableViewCell { + @IBOutlet weak var label: UILabel! + @IBOutlet weak var qrCode: UIImageView! +} diff --git a/enzevalos_iphone/Info.plist b/enzevalos_iphone/Info.plist index ec6a7aa3..54264407 100644 --- a/enzevalos_iphone/Info.plist +++ b/enzevalos_iphone/Info.plist @@ -24,22 +24,6 @@ <string>1</string> <key>LSRequiresIPhoneOS</key> <true/> - <key>NSContactsUsageDescription</key> - <string>To resolve the mailaddresses to your contacts, we need to access them</string> - <key>UILaunchStoryboardName</key> - <string>LaunchScreen</string> - <key>UIMainStoryboardFile</key> - <string>Main</string> - <key>UIRequiredDeviceCapabilities</key> - <array> - <string>armv7</string> - </array> - <key>UISupportedInterfaceOrientations</key> - <array> - <string>UIInterfaceOrientationPortrait</string> - <string>UIInterfaceOrientationLandscapeLeft</string> - <string>UIInterfaceOrientationLandscapeRight</string> - </array> <key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> @@ -55,7 +39,7 @@ <key>NSTemporaryExceptionRequiresForwardSecrecy</key> <false/> </dict> - <key>zedat.fu-berlin.de</key> + <key>mail.zedat.fu-berlin.de</key> <dict> <key>NSIncludesSubdomains</key> <true/> @@ -66,7 +50,7 @@ <key>NSTemporaryExceptionRequiresForwardSecrecy</key> <false/> </dict> - <key>mail.zedat.fu-berlin.de</key> + <key>zedat.fu-berlin.de</key> <dict> <key>NSIncludesSubdomains</key> <true/> @@ -79,5 +63,23 @@ </dict> </dict> </dict> + <key>NSCameraUsageDescription</key> + <string>We need access to your camera to verify contacts with a QR code.</string> + <key>NSContactsUsageDescription</key> + <string>To resolve the mailaddresses to your contacts, we need to access them</string> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + <key>UIMainStoryboardFile</key> + <string>Main</string> + <key>UIRequiredDeviceCapabilities</key> + <array> + <string>armv7</string> + </array> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + <string>UIInterfaceOrientationLandscapeLeft</string> + <string>UIInterfaceOrientationLandscapeRight</string> + </array> </dict> </plist> diff --git a/enzevalos_iphone/QRCodeGenerator.swift b/enzevalos_iphone/QRCodeGenerator.swift new file mode 100644 index 00000000..385d6677 --- /dev/null +++ b/enzevalos_iphone/QRCodeGenerator.swift @@ -0,0 +1,27 @@ +// +// QRCodeGenerator.swift +// enzevalos_iphone +// +// Created by Joscha on 01.08.17. +// Copyright © 2017 fu-berlin. All rights reserved. +// +// https://www.appcoda.com/qr-code-generator-tutorial/ + +import Foundation + +class QRCode { + + static func generate(input: String) -> CIImage { + var qrCode: CIImage + + let data = input.data(using: String.Encoding.isoLatin1) + let filter = CIFilter(name: "CIQRCodeGenerator")! + + filter.setValue(data, forKey: "inputMessage") + filter.setValue("M", forKey: "inputCorrectionLevel") + + qrCode = filter.outputImage! + + return qrCode + } +} diff --git a/enzevalos_iphone/QRScannerView.swift b/enzevalos_iphone/QRScannerView.swift new file mode 100644 index 00000000..1d9772d3 --- /dev/null +++ b/enzevalos_iphone/QRScannerView.swift @@ -0,0 +1,152 @@ +// +// QRScannerView.swift +// enzevalos_iphone +// +// Created by Joscha on 01.08.17. +// Copyright © 2017 fu-berlin. All rights reserved. +// +// https://www.appcoda.com/barcode-reader-swift/ + +import AVFoundation +import AudioToolbox // necessary only to vibrate on versions before iOS 10 + +class QRScannerView: ViewControllerPannable, AVCaptureMetadataOutputObjectsDelegate { + @IBOutlet weak var topBar: UIView! + @IBOutlet weak var bottomBar: UIView! + @IBOutlet weak var topLabel: UILabel! + @IBOutlet weak var bottomLabel: UILabel! + + var captureSession: AVCaptureSession? + var videoPreviewLayer: AVCaptureVideoPreviewLayer? + var qrCodeFrameView: UIView? + var qrCodeFrameColor: UIColor? { + set { + if let frame = qrCodeFrameView { + frame.layer.borderColor = newValue?.cgColor + frame.layer.backgroundColor = newValue?.withAlphaComponent(0.4).cgColor + } + } + get { return nil } + } + + var fingerprint: String? + var callback: (() -> ())? + + override func viewDidLoad() { + super.viewDidLoad() + + topLabel.text = NSLocalizedString("verifyContact", comment: "") + bottomLabel.text = NSLocalizedString("scanQRCode", comment: "") + + let topBlurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark)) + let bottomBlurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark)) + topBlurView.frame = topBar.bounds + bottomBlurView.frame = bottomBar.bounds + topBlurView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + bottomBlurView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + topBar.addSubview(topBlurView) + topBar.sendSubview(toBack: topBlurView) + bottomBar.addSubview(bottomBlurView) + bottomBar.sendSubview(toBack: bottomBlurView) + + // Get an instance of the AVCaptureDevice class to initialize a device object and provide the video as the media type parameter. + let captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) + + do { + // Get an instance of the AVCaptureDeviceInput class using the previous device object. + let input = try AVCaptureDeviceInput(device: captureDevice) + + // Initialize the captureSession object. + captureSession = AVCaptureSession() + + // Set the input device on the capture session. + captureSession?.addInput(input) + + // Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session. + let captureMetadataOutput = AVCaptureMetadataOutput() + captureSession?.addOutput(captureMetadataOutput) + + // Set delegate and use the default dispatch queue to execute the call back + captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) + captureMetadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode] + + // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer. + videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) + videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill + videoPreviewLayer?.frame = view.layer.bounds + view.layer.addSublayer(videoPreviewLayer!) + + // Initialize QR Code Frame to highlight the QR code + qrCodeFrameView = UIView() + + if let qrCodeFrameView = qrCodeFrameView { + qrCodeFrameColor = UIColor.orange + qrCodeFrameView.layer.borderWidth = 2 + view.addSubview(qrCodeFrameView) + view.bringSubview(toFront: qrCodeFrameView) + } + + view.bringSubview(toFront: topBar) + view.bringSubview(toFront: bottomBar) + + // Start video capture. + captureSession?.startRunning() + } catch { + // If any error occurs, simply print it out and don't continue any more. + print(error) + return + } + } + + @IBAction func close(_ sender: Any) { + dismiss(animated: true, completion: nil) + } + + func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) { + + // Check if the metadataObjects array is not nil and it contains at least one object. + if metadataObjects == nil || metadataObjects.count == 0 { + qrCodeFrameView?.frame = CGRect.zero + bottomLabel.text = NSLocalizedString("scanQRCode", comment: "") + return + } + + // Get the metadata object. + let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject + + if metadataObj.type == AVMetadataObjectTypeQRCode { + // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds + let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj) + qrCodeFrameView?.frame = barCodeObject!.bounds + + if let string = metadataObj.stringValue { + if let fingerprint = fingerprint, string.hasPrefix("OPENPGP4FPR:") || string.hasPrefix("openpgp4fpr:") { + let seperated = string.components(separatedBy: ":") + if seperated[1] == fingerprint { +// let alert = UIAlertController() + qrCodeFrameColor = UIColor.green + captureSession?.stopRunning() + bottomLabel.text = NSLocalizedString("verifySuccess", comment: "Fingerprint was successfully verified") + if #available(iOS 10.0, *) { + let feedbackGenerator = UINotificationFeedbackGenerator() + feedbackGenerator.notificationOccurred(.success) + } else { + AudioServicesPlayAlertSound(kSystemSoundID_Vibrate) + } + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.5) { + self.dismiss(animated: true, completion: self.callback) + } + } else { + qrCodeFrameColor = UIColor.red + bottomLabel.text = NSLocalizedString("fingerprintMissmatch", comment: "Found fingerprint does not match") + // TODO: Add a more explicit warning? + } + } else { + //UIAlertView + qrCodeFrameColor = UIColor.orange + bottomLabel.text = NSLocalizedString("wrongQRCode", comment: "The found QR Code is not compatible") + } + } + } + } +} diff --git a/enzevalos_iphone/ViewControllerPannable.swift b/enzevalos_iphone/ViewControllerPannable.swift new file mode 100644 index 00000000..3acc2206 --- /dev/null +++ b/enzevalos_iphone/ViewControllerPannable.swift @@ -0,0 +1,55 @@ +// +// ViewControllerPannable.swift +// enzevalos_iphone +// +// Created by Joscha on 03.08.17. +// Copyright © 2017 fu-berlin. All rights reserved. +// +// https://stackoverflow.com/a/41077052 + +class ViewControllerPannable: UIViewController { + var panGestureRecognizer: UIPanGestureRecognizer? + var originalPosition: CGPoint? + var currentPositionTouched: CGPoint? + + override func viewDidLoad() { + super.viewDidLoad() + + panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panGestureAction(_:))) + view.addGestureRecognizer(panGestureRecognizer!) + } + + func panGestureAction(_ panGesture: UIPanGestureRecognizer) { + let translation = panGesture.translation(in: view) + + if panGesture.state == .began { + originalPosition = view.center + currentPositionTouched = panGesture.location(in: view) + } else if panGesture.state == .changed { + view.frame.origin = CGPoint( + x: 0, + y: translation.y + ) + } else if panGesture.state == .ended { + let velocity = panGesture.velocity(in: view) + + if velocity.y >= 1500 || translation.y >= 300 { + UIView.animate(withDuration: 0.2 + , animations: { + self.view.frame.origin = CGPoint( + x: self.view.frame.origin.x, + y: self.view.frame.size.height + ) + }, completion: { (isCompleted) in + if isCompleted { + self.dismiss(animated: false, completion: nil) + } + }) + } else { + UIView.animate(withDuration: 0.2, animations: { + self.view.center = self.originalPosition! + }) + } + } + } +} diff --git a/enzevalos_iphone/de.lproj/Localizable.strings b/enzevalos_iphone/de.lproj/Localizable.strings index 5c3c6201..5fd8ff3a 100644 --- a/enzevalos_iphone/de.lproj/Localizable.strings +++ b/enzevalos_iphone/de.lproj/Localizable.strings @@ -137,8 +137,14 @@ "inviteText" = "Hallo!\n\nEs gibt eine neue App die es super einfach macht verschlüsselt über E-Mail zu kommunizieren. Sie heißt Enzevalos und ist kostenlos im App Store zu finden.\n\nEs wäre toll wenn du sie mal ausprobieren würdest!\n\nViele Grüße!"; "noName" = "OHNE NAME"; "you" = "Deine Ablage"; -"thisIsYou" = "Hier werden E-Mails die du dir selber schickst gesammelt"; +"thisIsYou" = "Hier werden E-Mails, die du dir selber schickst, gesammelt"; "didYouSendThis" = "Hallo, haben Sie mir diese E-Mail geschickt?\nIch frage nur, weil die E-Mail unsicher versendet wurde.\n\n"; "reactButton" = "Bestätigung erfragen"; "sendSecureIfPossible" = "Sicher versenden"; "sendInsecure" = "Unsicher versenden"; +"verifyContact" = "Kontakt verifizieren"; +"scanQRCode" = "Scanne den QR Code des Kontaktes"; +"wrongQRCode" = "Kein passender QR Code gefunden"; +"fingerprintMissmatch" = "Der Fingerabdruck stimmt nicht überein!"; +"verifySuccess" = "Erfolgreich verifiziert!"; +"yourFingerprint" = "Dein Fingerabdruck:"; diff --git a/enzevalos_iphone/en.lproj/Localizable.strings b/enzevalos_iphone/en.lproj/Localizable.strings index 9339cbde..1e7618d0 100644 --- a/enzevalos_iphone/en.lproj/Localizable.strings +++ b/enzevalos_iphone/en.lproj/Localizable.strings @@ -141,3 +141,9 @@ "reactButton" = "Request Confirmation"; "sendSecureIfPossible" = "Send secure"; "sendInsecure" = "Send insecure"; +"verifyContact" = "Verify Contact"; +"scanQRCode" = "Scan the QR Code of the Contact"; +"wrongQRCode" = "Incompatible QR Code found"; +"fingerprintMissmatch" = "The found Fingerprint does not match!"; +"verifySuccess" = "Successfully verified!"; +"yourFingerprint" = "Your Fingerprint:"; -- GitLab