diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj index bf949a98102cbdf44a6d58b6a72f4d82df2ae543..0eccd46c82fafebd2bfd268094299ea4746bc577 100644 --- a/enzevalos_iphone.xcodeproj/project.pbxproj +++ b/enzevalos_iphone.xcodeproj/project.pbxproj @@ -50,7 +50,6 @@ 3E9708D91FAC95F5005825C9 /* QRScannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F113C3841F30D06800E7F1D6 /* QRScannerView.swift */; }; 3E9708DA1FAC95F5005825C9 /* PGPCryptoCFB.m in Sources */ = {isa = PBXBuildFile; fileRef = 471BC8DB1F960B7C00D64416 /* PGPCryptoCFB.m */; }; 3E9708DB1FAC95F5005825C9 /* ReplaceSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = F18B445F1E704C550080C041 /* ReplaceSegue.swift */; }; - 3E9708DC1FAC95F5005825C9 /* old.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472F39871E1FA377009260FB /* old.swift */; }; 3E9708DD1FAC95F5005825C9 /* ArrowTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8428A8611F436A11007649A5 /* ArrowTableViewCell.swift */; }; 3E9708DE1FAC95F5005825C9 /* ContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1ACF21B1E0C1C6800C1B843 /* ContactViewController.swift */; }; 3E9708DF1FAC95F5005825C9 /* CryptoObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 475B00321F7B9565006CDD41 /* CryptoObject.swift */; }; @@ -243,7 +242,6 @@ 472F39811E1E5347009260FB /* Mail_Address+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472F397F1E1E5347009260FB /* Mail_Address+CoreDataClass.swift */; }; 472F39821E1E5347009260FB /* Mail_Address+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472F39801E1E5347009260FB /* Mail_Address+CoreDataProperties.swift */; }; 472F39861E1FA34E009260FB /* Record.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472F39851E1FA34E009260FB /* Record.swift */; }; - 472F39881E1FA377009260FB /* old.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472F39871E1FA377009260FB /* old.swift */; }; 472F398A1E251787009260FB /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472F39891E251787009260FB /* Contact.swift */; }; 472F398C1E2519C8009260FB /* CNContactExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472F398B1E2519C8009260FB /* CNContactExtension.swift */; }; 472F398E1E251B8D009260FB /* MailAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 472F398D1E251B8D009260FB /* MailAddress.swift */; }; @@ -535,7 +533,6 @@ 472F397F1E1E5347009260FB /* Mail_Address+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Mail_Address+CoreDataClass.swift"; sourceTree = "<group>"; }; 472F39801E1E5347009260FB /* Mail_Address+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Mail_Address+CoreDataProperties.swift"; sourceTree = "<group>"; }; 472F39851E1FA34E009260FB /* Record.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Record.swift; sourceTree = "<group>"; }; - 472F39871E1FA377009260FB /* old.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = old.swift; sourceTree = "<group>"; }; 472F39891E251787009260FB /* Contact.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Contact.swift; sourceTree = "<group>"; }; 472F398B1E2519C8009260FB /* CNContactExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CNContactExtension.swift; sourceTree = "<group>"; }; 472F398D1E251B8D009260FB /* MailAddress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MailAddress.swift; sourceTree = "<group>"; }; @@ -1006,7 +1003,6 @@ A114E4311FACB23000E40243 /* StringExtension.swift */, 47691A8B1ECC3EC7004BCFC5 /* EphemeralMail.swift */, 472F398B1E2519C8009260FB /* CNContactExtension.swift */, - 472F39871E1FA377009260FB /* old.swift */, 472F398F1E252470009260FB /* CNMailAddressesExtension.swift */, A1EB05871D956879008659C1 /* AddressHandler.swift */, 47B91AC01EC0C1CF000AE3EE /* coredata */, @@ -1473,7 +1469,7 @@ CreatedOnToolsVersion = 7.3.1; DevelopmentTeam = VJ9C93G68Y; LastSwiftMigration = 0820; - ProvisioningStyle = Manual; + ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.Keychain = { enabled = 1; @@ -1922,7 +1918,6 @@ 473AC3A620054DFB006EB8A6 /* PGPSignatureSubpacketEmbeddedSignature.m in Sources */, 3E9708DA1FAC95F5005825C9 /* PGPCryptoCFB.m in Sources */, 3E9708DB1FAC95F5005825C9 /* ReplaceSegue.swift in Sources */, - 3E9708DC1FAC95F5005825C9 /* old.swift in Sources */, 3E9708DD1FAC95F5005825C9 /* ArrowTableViewCell.swift in Sources */, 3E9708DE1FAC95F5005825C9 /* ContactViewController.swift in Sources */, 3E9708DF1FAC95F5005825C9 /* CryptoObject.swift in Sources */, @@ -2071,7 +2066,6 @@ 471BC9231F960B7C00D64416 /* PGPCryptoCFB.m in Sources */, 473AC39320054D07006EB8A6 /* PGPUserAttributeImageSubpacket.m in Sources */, F18B44601E704C550080C041 /* ReplaceSegue.swift in Sources */, - 472F39881E1FA377009260FB /* old.swift in Sources */, 8428A8661F436A11007649A5 /* ArrowTableViewCell.swift in Sources */, F1ACF21C1E0C1C6800C1B843 /* ContactViewController.swift in Sources */, 475B00351F7B9565006CDD41 /* CryptoObject.swift in Sources */, @@ -2480,8 +2474,9 @@ CODE_SIGN_ENTITLEMENTS = enzevalos_iphone/PLists/enzevalos_iphone.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = NO; - DEVELOPMENT_TEAM = VJ9C93G68Y; + DEVELOPMENT_TEAM = ""; GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_FILE = "enzevalos_iphone/PLists/enzevalos-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.3; @@ -2514,8 +2509,8 @@ OTHER_SWIFT_FLAGS = "$(inherited) -D DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "fu-berlin.enzevalos-iphone"; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = "3aaeb64f-5416-4e9e-a6ee-2cb191401818"; - PROVISIONING_PROFILE_SPECIFIER = "SMF Enterprise Wildcard DEBUG"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "enzevalos_iphone-Bridging-Header.h"; "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = "enzevalos_iphone/enzevalos_iphone-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -2533,8 +2528,9 @@ CODE_SIGN_ENTITLEMENTS = enzevalos_iphone/PLists/enzevalos_iphone.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = NO; - DEVELOPMENT_TEAM = VJ9C93G68Y; + DEVELOPMENT_TEAM = ""; GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_FILE = "enzevalos_iphone/PLists/enzevalos-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.3; @@ -2567,8 +2563,8 @@ OTHER_SWIFT_FLAGS = "$(inherited) -D RELEASE"; PRODUCT_BUNDLE_IDENTIFIER = "fu-berlin.enzevalos-iphone"; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = "3aaeb64f-5416-4e9e-a6ee-2cb191401818"; - PROVISIONING_PROFILE_SPECIFIER = "SMF Enterprise Wildcard DEBUG"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "enzevalos_iphone-Bridging-Header.h"; "SWIFT_OBJC_BRIDGING_HEADER[sdk=*]" = "enzevalos_iphone/enzevalos_iphone-Bridging-Header.h"; SWIFT_VERSION = 3.0; diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/Contents.json b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/Contents.json index eade96677f09e8c195d9f3f9d0a76685a1a72f53..5815f81311dc177bc8c7cab6861b2b15c618dd85 100644 --- a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/Contents.json +++ b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/Contents.json @@ -2,17 +2,17 @@ "images" : [ { "idiom" : "universal", - "filename" : "invite_censorReceiver.png", + "filename" : "_source.png", "scale" : "1x" }, { "idiom" : "universal", - "filename" : "invite_censorReceiver@2x.png", + "filename" : "_source@2x.png", "scale" : "2x" }, { "idiom" : "universal", - "filename" : "invite_censorReceiver@3x.png", + "filename" : "_source@3x.png", "scale" : "3x" } ], diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/_source.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/_source.png new file mode 100644 index 0000000000000000000000000000000000000000..b943224b88bb94ae1f939530006b389a5ab39dc3 Binary files /dev/null and b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/_source.png differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/_source@2x.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/_source@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f1e48c276ad5d8e6aa05e240bf49fa80a0563ff8 Binary files /dev/null and b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/_source@2x.png differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/_source@3x.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/_source@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..c7714d47094d5abaae0fe5ee481e1285595be87e Binary files /dev/null and b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/_source@3x.png differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/invite_censorReceiver.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/invite_censorReceiver.png deleted file mode 100644 index dedb8892b34819465317dc73302db3e433b63151..0000000000000000000000000000000000000000 Binary files a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/invite_censorReceiver.png and /dev/null differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/invite_censorReceiver@2x.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/invite_censorReceiver@2x.png deleted file mode 100644 index 435fb56f80e2dbeebdf2799960c38682243d5f1f..0000000000000000000000000000000000000000 Binary files a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/invite_censorReceiver@2x.png and /dev/null differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/invite_censorReceiver@3x.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/invite_censorReceiver@3x.png deleted file mode 100644 index c3865a358bcecbf2c4bb0681ce80f5dc94f59e4f..0000000000000000000000000000000000000000 Binary files a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_receiver.imageset/invite_censorReceiver@3x.png and /dev/null differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/Contents.json b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/Contents.json index 9726bf7bc6f9f8324ca4fe330bb462f6e5633b1f..45f736cdb081c4db861460ddb752fa75b2b57c95 100644 --- a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/Contents.json +++ b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/Contents.json @@ -2,17 +2,17 @@ "images" : [ { "idiom" : "universal", - "filename" : "invite_censorSender.png", + "filename" : "markiert.png", "scale" : "1x" }, { "idiom" : "universal", - "filename" : "invite_censorSender@2x.png", + "filename" : "markiert@2x.png", "scale" : "2x" }, { "idiom" : "universal", - "filename" : "invite_censorSender@3x.png", + "filename" : "markiert@3x.png", "scale" : "3x" } ], diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/invite_censorSender.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/invite_censorSender.png deleted file mode 100644 index 720070ac4376d3a33a80e71d424c80f3ab86bf56..0000000000000000000000000000000000000000 Binary files a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/invite_censorSender.png and /dev/null differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/invite_censorSender@2x.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/invite_censorSender@2x.png deleted file mode 100644 index 429959e67e0fa083acfbb206aac8a62952cfb85a..0000000000000000000000000000000000000000 Binary files a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/invite_censorSender@2x.png and /dev/null differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/invite_censorSender@3x.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/invite_censorSender@3x.png deleted file mode 100644 index d6c4701344e8360c2e17f1e23f46873203036df5..0000000000000000000000000000000000000000 Binary files a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/invite_censorSender@3x.png and /dev/null differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/markiert.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/markiert.png new file mode 100644 index 0000000000000000000000000000000000000000..1b11b4c810121454069333a7b8a24561431cb81b Binary files /dev/null and b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/markiert.png differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/markiert@2x.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/markiert@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5e31c2cae2295a02438c1ad47a948fbab9e2a82c Binary files /dev/null and b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/markiert@2x.png differ diff --git a/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/markiert@3x.png b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/markiert@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f355e886fe7faa145565d1de6e714181bb3e9f3c Binary files /dev/null and b/enzevalos_iphone/Assets.xcassets/Invitation/bg_inviation_censor_sender.imageset/markiert@3x.png differ diff --git a/enzevalos_iphone/Base.lproj/Main.storyboard b/enzevalos_iphone/Base.lproj/Main.storyboard index ba61e611c3eb214823adc925529e0460b92e646c..59c4e58da86979f2d5f14ebaaed0715805c5a978 100644 --- a/enzevalos_iphone/Base.lproj/Main.storyboard +++ b/enzevalos_iphone/Base.lproj/Main.storyboard @@ -705,15 +705,15 @@ <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalCentering" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="OlN-1g-hBJ"> <rect key="frame" x="21" y="38.5" width="15" height="24"/> <subviews> - <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="imI-nB-es5"> - <rect key="frame" x="0.0" y="0.0" width="15" height="15"/> + <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="imI-nB-es5"> + <rect key="frame" x="0.0" y="0.0" width="15" height="9"/> <constraints> <constraint firstAttribute="height" constant="15" id="NJi-27-Up8"/> <constraint firstAttribute="width" constant="15" id="auJ-Nm-E8J"/> </constraints> </imageView> - <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C7X-Yt-kz2"> - <rect key="frame" x="0.0" y="15" width="15" height="9"/> + <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="C7X-Yt-kz2"> + <rect key="frame" x="0.0" y="9" width="15" height="15"/> <constraints> <constraint firstAttribute="width" constant="15" id="Sjh-9U-pfX"/> <constraint firstAttribute="height" constant="15" id="sLj-Te-fV3"/> @@ -771,7 +771,7 @@ <objects> <tableViewController storyboardIdentifier="UITableViewController-ooe-0X-glz" id="ooe-0X-glz" customClass="ListViewController" customModule="enzevalos_iphone" customModuleProvider="target" sceneMemberID="viewController"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="ipK-4X-lVA"> - <rect key="frame" x="0.0" y="0.0" width="320" height="568"/> + <rect key="frame" x="0.0" y="0.0" width="320" height="504"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <prototypes> @@ -857,7 +857,7 @@ <objects> <tableViewController storyboardIdentifier="UITableViewController-8Di-x2-cWQ" id="8Di-x2-cWQ" customClass="ContactViewController" customModule="enzevalos_iphone" customModuleProvider="target" sceneMemberID="viewController"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="lK7-ug-OyQ"> - <rect key="frame" x="0.0" y="0.0" width="320" height="568"/> + <rect key="frame" x="0.0" y="0.0" width="320" height="504"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/> <prototypes> @@ -1120,11 +1120,11 @@ <rect key="frame" x="0.0" y="545.5" width="320" 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="286" height="43.5"/> + <rect key="frame" x="0.0" y="0.0" width="287" 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="269" height="43.5"/> + <rect key="frame" x="15" y="0.0" width="270" height="43.5"/> <autoresizingMask key="autoresizingMask"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <nil key="textColor"/> @@ -1220,10 +1220,10 @@ <objects> <viewController id="jYD-fk-aIP" customClass="KeyViewController" customModule="enzevalos_iphone" customModuleProvider="target" sceneMemberID="viewController"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="ZAH-bZ-S6n"> - <rect key="frame" x="0.0" y="0.0" width="320" height="568"/> + <rect key="frame" x="0.0" y="0.0" width="320" height="504"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/> - <button key="tableFooterView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="KaX-Vg-m5j"> + <button key="tableFooterView" opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="KaX-Vg-m5j"> <rect key="frame" x="0.0" y="425.5" width="320" height="44"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="15"/> @@ -1393,7 +1393,7 @@ <objects> <tableViewController id="7Pd-d5-0wz" customClass="ExportInfoViewController" customModule="enzevalos_iphone" customModuleProvider="target" sceneMemberID="viewController"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" dataMode="prototypes" style="grouped" separatorStyle="default" sectionIndexMinimumDisplayRowCount="1" rowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="2Uv-bd-pB1"> - <rect key="frame" x="0.0" y="0.0" width="320" height="568"/> + <rect key="frame" x="0.0" y="0.0" width="320" height="504"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/> <prototypes> @@ -1405,7 +1405,7 @@ <autoresizingMask key="autoresizingMask"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="QmG-XY-YlD"> - <rect key="frame" x="16" y="11" width="288" height="645"/> + <rect key="frame" x="16" y="11" width="288" height="625"/> <subviews> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="clip" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IEj-77-gTt"> <rect key="frame" x="3" y="5" width="272" height="243.5"/> @@ -1431,8 +1431,8 @@ Um deine sicheren E-Mails auch auf einem anderen Gerät lesen zu können, muss d <constraint firstAttribute="height" constant="200" id="MVu-ar-vWo"/> </constraints> </imageView> - <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" bouncesZoom="NO" editable="NO" text="https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#otherDevices" textAlignment="center" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xud-17-hsu"> - <rect key="frame" x="59" y="514.5" width="169" height="117.5"/> + <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" bouncesZoom="NO" editable="NO" text="https://userpage.fu-berlin.de/letterbox/faq.html#otherDevices" textAlignment="center" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xud-17-hsu"> + <rect key="frame" x="59" y="514.5" width="169" height="97.5"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/> @@ -1494,7 +1494,7 @@ Um deine sicheren E-Mails auch auf einem anderen Gerät lesen zu können, muss d <objects> <tableViewController id="Dxf-zr-T68" customClass="ExportViewController" customModule="enzevalos_iphone" customModuleProvider="target" sceneMemberID="viewController"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="1" sectionHeaderHeight="18" sectionFooterHeight="18" id="h3p-jv-yUQ"> - <rect key="frame" x="0.0" y="0.0" width="320" height="568"/> + <rect key="frame" x="0.0" y="0.0" width="320" height="504"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/> <prototypes> diff --git a/enzevalos_iphone/ContactViewController.swift b/enzevalos_iphone/ContactViewController.swift index 95ce11bd2fcdf576884b872cb5f14c7d77c28523..b0b1687b268cb11587729927e898a64aa8480b0c 100644 --- a/enzevalos_iphone/ContactViewController.swift +++ b/enzevalos_iphone/ContactViewController.swift @@ -177,7 +177,7 @@ class ContactViewController: UIViewController { tableView.selectRow(at: myPath, animated: false, scrollPosition: .none) performSegue(withIdentifier: "otherRecord", sender: 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) + let mail = EphemeralMail(to: NSSet.init(array: keyRecord!.addresses), cc: NSSet.init(), bcc: NSSet.init(), date: Date(), subject: NSLocalizedString("inviteSubject", comment: ""), body: String(format: NSLocalizedString("inviteText", comment: ""),StudySettings.studyID), uid: 0, predecessor: nil) performSegue(withIdentifier: "newMail", sender: mail) } else if sender.titleLabel?.text == NSLocalizedString("verifyNow", comment: "Verify now") { AppUtility.lockOrientation(.portrait, andRotateTo: .portrait) diff --git a/enzevalos_iphone/DataHandler.swift b/enzevalos_iphone/DataHandler.swift index 42097f96e65d14990c0f5b460b10b77ef75bc754..2ed6ad5262812cd646190fef696a7a390aa9968a 100644 --- a/enzevalos_iphone/DataHandler.swift +++ b/enzevalos_iphone/DataHandler.swift @@ -264,17 +264,6 @@ class DataHandler { } } - private func delete(_ entityName: String, type: String, search: String) { - let fReq: NSFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName) - fReq.predicate = NSPredicate(format: "\(type) LIKE [cd] ", search) //FIXME: Was ist hier mit Injections? Vorsicht wo das verwendet wird! Nicht, dass hier UI Eingaben reinkommen können... https://stackoverflow.com/questions/3076894/how-to-prevent-sql-injection-in-core-data#3078076 - if let result = (try? self.managedObjectContext.fetch(fReq)) as? [NSManagedObject] { - for object in result { - self.managedObjectContext.delete(object) - } - save(during: "deleting") - } - } - private func deleteNum(_ entityName: String, type: String, search: UInt64) { let fReq: NSFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName) fReq.predicate = NSPredicate(format: "\(type) = %D ", search) @@ -282,7 +271,7 @@ class DataHandler { for object in result { self.managedObjectContext.delete(object) } - save(during: "Delte num") + save(during: "delete num") } } diff --git a/enzevalos_iphone/Dialog/DialogOption.swift b/enzevalos_iphone/Dialog/DialogOption.swift index d70e87ba5e3028d7ed7efab4d783fa2b543aef81..01128250c801bd45e16169433eddd1034e3f43bd 100644 --- a/enzevalos_iphone/Dialog/DialogOption.swift +++ b/enzevalos_iphone/Dialog/DialogOption.swift @@ -14,6 +14,7 @@ enum DialogOption { case invitationCode(code: String) case invitationWelcome case invitationStep + case invitationHelp var color: UIColor { switch self { @@ -21,6 +22,7 @@ enum DialogOption { case .invitationCode : return UIColor.Invitation.orange case .invitationWelcome : return UIColor.Invitation.orange case .invitationStep : return UIColor.Invitation.orange + case .invitationHelp : return UIColor.Invitation.orange } } @@ -28,17 +30,22 @@ enum DialogOption { switch self { case .postcard : return nil case .invitationCode : return nil - case .invitationWelcome : - if StudySettings.invitationsmode == InvitationMode.Censorship { - var images = [UIImage]() - if let sender = UIImage(named: "bg_inviation_censor_sender"), let receiver = UIImage(named: "bg_inviation_censor_receiver") { - images.append(sender) - images.append(receiver) - return UIImage.animatedImage(with: images, duration: 3) - } - + case .invitationWelcome, .invitationHelp : + switch StudySettings.invitationsmode { + case InvitationMode.Censorship: + var images = [UIImage]() + if let sender = UIImage(named: "bg_inviation_censor_sender"), let receiver = UIImage(named: "bg_inviation_censor_receiver") { + images.append(sender) + images.append(receiver) + return UIImage.animatedImage(with: images, duration: 4) + } + return nil + case .PasswordEnc: + return UIImage(named: "bg_inviation") + case .FreeText, + .InviteMail: + return UIImage(named: "postcard") } - return UIImage(named: "bg_inviation") case .invitationStep : return nil } } @@ -47,7 +54,8 @@ enum DialogOption { switch self { case .postcard : return UIImage(named: "letter") case .invitationCode : return UIImage(named: "ic_secure_card") - case .invitationWelcome : return nil + case .invitationWelcome, + .invitationHelp : return nil case .invitationStep : return UIImage(named: "ic_secure_card") } } @@ -56,7 +64,8 @@ enum DialogOption { switch self { case .postcard : return "Welcome" case .invitationCode : return NSLocalizedString("Invitation.Code.Title", comment: "") - case .invitationWelcome : return NSLocalizedString("Invitation.Welcome.Title", comment: "") + case .invitationWelcome, + .invitationHelp : return NSLocalizedString("Invitation.Welcome.Title", comment: "") case .invitationStep : return NSLocalizedString("Invitation.Step.Title", comment: "") } } @@ -64,12 +73,19 @@ enum DialogOption { var message: String? { switch self { case .postcard : return "Message\nMultiline and long texts are allowed, btw second button is hidden" - case .invitationWelcome : + case .invitationWelcome, + .invitationHelp : + switch StudySettings.invitationsmode { + case .Censorship : return NSLocalizedString("Invitation.Welcome.Message.Censor", comment: "") + case .FreeText, + .InviteMail : return NSLocalizedString("Invitation.Welcome.Message.InvitationMail", comment: "") + case .PasswordEnc : return NSLocalizedString("Invitation.Welcome.Message", comment: "") + } + case .invitationStep : if StudySettings.invitationsmode == InvitationMode.Censorship{ - return NSLocalizedString("Invitation.Welcome.Message.Censor", comment: "") + return NSLocalizedString("Invitation.Step.Message.Censor", comment: "") } - return NSLocalizedString("Invitation.Welcome.Message", comment: "") - case .invitationStep : return NSLocalizedString("Invitation.Step.Message", comment: "") + return NSLocalizedString("Invitation.Step.Message", comment: "") case .invitationCode(let code) : if StudySettings.invitationsmode == InvitationMode.Censorship{ return "" @@ -82,8 +98,15 @@ enum DialogOption { switch self { case .postcard : return "Freunde einladen" case .invitationCode : return NSLocalizedString("Invitation.Code.Share", comment: "") - case .invitationWelcome : return NSLocalizedString("Invitation.Welcome.Try", comment: "") + case .invitationWelcome : + switch StudySettings.invitationsmode { + case .FreeText, + .InviteMail : return NSLocalizedString("Invitation.Welcome.Try.InvitationMail", comment: "") + case .Censorship, + .PasswordEnc : return NSLocalizedString("Invitation.Welcome.Try", comment: "") + } case .invitationStep : return NSLocalizedString("Invitation.Step.CTA", comment: "") + case .invitationHelp : return NSLocalizedString("Done", comment: "") } } @@ -92,7 +115,8 @@ enum DialogOption { case .postcard : return "Mehr Informationen" case .invitationCode : return nil case .invitationWelcome : return NSLocalizedString("Invitation.Welcome.Later", comment: "") - case .invitationStep : return nil + case .invitationStep : return nil + case .invitationHelp : return nil } } @@ -102,6 +126,7 @@ enum DialogOption { case .invitationCode : return NSLocalizedString("Invitation.Code.Done", comment: "") case .invitationWelcome : return NSLocalizedString("Invitation.Welcome.Dont.Ask", comment: "") case .invitationStep : return NSLocalizedString("Invitation.Step.Undo", comment: "") + case .invitationHelp : return nil } } } diff --git a/enzevalos_iphone/Dialog/DialogViewController.swift b/enzevalos_iphone/Dialog/DialogViewController.swift index 09db3cc1c22f6d3637b95b933d0ec70df87b6e9d..7c51d692f5318046adceb91159ef6571538808b9 100644 --- a/enzevalos_iphone/Dialog/DialogViewController.swift +++ b/enzevalos_iphone/Dialog/DialogViewController.swift @@ -172,7 +172,11 @@ extension DialogViewController { @IBAction private func ctaButtonTapped(sender: Any) { - self.ctaAction?() + self.hideDialog(true) { [weak self] in + self?.dismiss(animated: false, completion: { [weak self] in + self?.ctaAction?() + }) + } } @IBAction private func additionalButtonTapped(sender: Any) { diff --git a/enzevalos_iphone/ExportInfoViewController.swift b/enzevalos_iphone/ExportInfoViewController.swift index 41ce3c9aae3d7e96917006c27ba4291d369dee18..2e4e316d11cb438c0b97e4f04fc8e156393b4098 100644 --- a/enzevalos_iphone/ExportInfoViewController.swift +++ b/enzevalos_iphone/ExportInfoViewController.swift @@ -9,8 +9,7 @@ import UIKit class ExportInfoViewController: UITableViewController { - //TODO: maybe change url; create website! - let url = "userpage.fu-berlin.de/wieseoli/letterbox/faq.html#otherDevices" + let url = "userpage.fu-berlin.de/letterbox/faq.html#otherDevices" @IBAction func websiteButtonTouch(_ sender: Any) { UIApplication.shared.openURL(URL(string: "https://"+url)!) diff --git a/enzevalos_iphone/Invitation/invitationText.html b/enzevalos_iphone/Invitation/invitationText.html index 47e2b467a4f66fa487a189df18fb3c56c0ae4c5e..6d889174447e87c833f3d1159b364c8db872df79 100644 --- a/enzevalos_iphone/Invitation/invitationText.html +++ b/enzevalos_iphone/Invitation/invitationText.html @@ -58,7 +58,11 @@ </div> <hr> <a href="%@"><div class="alert-container"><div class="alert-icon"><svg fill="#ffffff" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0z" fill="none"/><path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/></svg></div><div class="alert-text">Teile dieser E-Mail sind verschlüsselt!</div></div></a> - Teile dieser Nachricht wurden zu gunsten der Privatsphäre verschlüsselt. Aber keine Angst du kannst die verschlüsselten Wörter jederzeit <a href="%@">hier</a> abrufen. + Eine unverschlüsselte E-Mail ist wie eine Postkarte; der E-Mail-Provider und möglicherweise auch Andere können mitlesen. Einige Teile dieser Nachricht sind privat oder pikant. Sie sollen vor Mitlesern verborgen bleiben und wurden darum geschwärzt.<br>Dein Gegenüber nutzt mit Letterbox bereits ein Programm um die Kommunikation vor den neugierigen Augen Anderer zu schützen. Wenn Du auch mitmachst, erreicht ihr beide gemeinsam das Ziel.<br>Du kannst die verschlüsselten Wörter jederzeit <a href="%@">hier</a> entschlüsseln. + <br> + <div class="body-text"> + %@ + </div> </body> </html> diff --git a/enzevalos_iphone/Invitation/invitationTextCensor.html b/enzevalos_iphone/Invitation/invitationTextCensor.html index 66ec12e5aae290072d1f88a1061f563974d6f90f..35118781e0cae08600049eac03ff6912d23baf57 100644 --- a/enzevalos_iphone/Invitation/invitationTextCensor.html +++ b/enzevalos_iphone/Invitation/invitationTextCensor.html @@ -55,8 +55,12 @@ %@ </div> <hr> - <a href="%@"><div class="alert-container"><div class="alert-icon"><svg fill="#ffffff" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0z" fill="none"/><path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/></svg></div><div class="alert-text">Teile dieser E-Mail sind verschlüsselt!</div></div></a> - Teile dieser Nachricht wurden zu gunsten der Privatsphäre verschlüsselt. Aber keine Angst du kannst die verschlüsselten Wörter jederzeit <a href="%@">hier</a> abrufen. + <a href="%@"><div class="alert-container"><div class="alert-icon"><svg fill="#ffffff" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0z" fill="none"/><path d="M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"/></svg></div><div class="alert-text">Warum ist nicht alles lesbar?</div></div></a> + Eine unverschlüsselte E-Mail ist wie eine Postkarte; der E-Mail-Provider und möglicherweise auch Andere können mitlesen. Einige Teile dieser Nachricht sind privat oder pikant. Sie sollen vor Mitlesern verborgen bleiben und wurden darum geschwärzt.<br>Dein Gegenüber nutzt mit Letterbox bereits ein Programm um die Kommunikation vor den neugierigen Augen Anderer zu schützen. Wenn Du auch mitmachst, erreicht ihr beide gemeinsam das Ziel.<br>Mehr Informationen finden sich <a href="%@">hier</a>. + <br> + <div class="body-text"> + %@ + </div> </body> </html> diff --git a/enzevalos_iphone/InviteFriendViewController.swift b/enzevalos_iphone/InviteFriendViewController.swift index a5e50e6ad921216748ef16dc70873d4db5c7f3f4..be646adfdac853000a8b412a98a3d45136d6ee70 100755 --- a/enzevalos_iphone/InviteFriendViewController.swift +++ b/enzevalos_iphone/InviteFriendViewController.swift @@ -221,7 +221,7 @@ class InviteFriendViewController: UIViewController, UITableViewDataSource, UITab if let controller = navigationController?.topViewController as? SendViewController, self.selectedContact != nil { let sendTo = selectedContact!.getMailAddresses() - let body = NSLocalizedString("inviteText", comment: "Body for the invitation mail") + let body = String(format: NSLocalizedString("inviteText", comment: "Body for the invitation mail"), StudySettings.studyID) let time = DateFormatter.init() time.dateStyle = .short time.timeStyle = .short diff --git a/enzevalos_iphone/Logger.swift b/enzevalos_iphone/Logger.swift index ee00a439a20c628e2155deecf84ad3fbf7a4ee29..6306b9e8986f7f05665f12055ba86c6d39025249 100644 --- a/enzevalos_iphone/Logger.swift +++ b/enzevalos_iphone/Logger.swift @@ -394,7 +394,7 @@ class Logger { sendCheck() } - static func log(sent from: Mail_Address, to: [Mail_Address], cc: [Mail_Address], bcc: [Mail_Address], subject: String, bodyLength: Int, isEncrypted: Bool, decryptedBodyLength: Int, decryptedWithOldPrivateKey: Bool = false, isSigned: Bool, isCorrectlySigned: Bool = true, signingKeyID: String, myKeyID: String, secureAddresses: [Mail_Address] = [], encryptedForKeyIDs: [String] = [], inviteMailContent: String?) { + static func log(sent from: Mail_Address, to: [Mail_Address], cc: [Mail_Address], bcc: [Mail_Address], subject: String, bodyLength: Int, isEncrypted: Bool, decryptedBodyLength: Int, decryptedWithOldPrivateKey: Bool = false, isSigned: Bool, isCorrectlySigned: Bool = true, signingKeyID: String, myKeyID: String, secureAddresses: [Mail_Address] = [], encryptedForKeyIDs: [String] = [], inviteMailContent: String?, invitationMail: Bool) { if !logging { return @@ -424,7 +424,14 @@ class Logger { } saveToDisk(json: dictToJSON(fields: event)) - sendCheck() + if invitationMail { + sendLog() + } + else { + sendCheck() + } + + } static func log(readViewOpen mail: PersistentMail, message: String, draft: Bool = false) { diff --git a/enzevalos_iphone/MailHandler.swift b/enzevalos_iphone/MailHandler.swift index 51461a6ba42d03e249537756e7d6436dd0fa569e..e888f0bde1127df4e6882d1e55d355b542e4ef3f 100644 --- a/enzevalos_iphone/MailHandler.swift +++ b/enzevalos_iphone/MailHandler.swift @@ -247,7 +247,7 @@ class MailHandler { builder.header.setExtraHeaderValue("v0", forName: SETUPMESSAGE) - builder.addAttachment(MCOAttachment.init(text: "This message contains a secret for reading secure mails on other devices. \n 1) Input the passcode from your smartphone to unlock the message on your other device. \n 2) Import the secret key into your pgp program on the device. \n\n For more information visit:https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#otherDevices \n\n")) + builder.addAttachment(MCOAttachment.init(text: "This message contains a secret for reading secure mails on other devices. \n 1) Input the passcode from your smartphone to unlock the message on your other device. \n 2) Import the secret key into your pgp program on the device. \n\n For more information visit:https://userpage.fu-berlin.de/letterbox/faq.html#otherDevices \n\n")) // See: https://autocrypt.org/level1.html#autocrypt-setup-message let keyAttachment = MCOAttachment.init(text: key) @@ -268,8 +268,8 @@ class MailHandler { } //logMail should be false, if called from Logger, otherwise - func send(_ toEntrys: [String], ccEntrys: [String], bccEntrys: [String], subject: String, message: String, sendEncryptedIfPossible: Bool = true, callback: @escaping (Error?) -> Void, loggingMail: Bool = false, isHTMLContent: Bool = false, warningReact: Bool = false, inviteMail: Bool = false) { - + func send(_ toEntrys: [String], ccEntrys: [String], bccEntrys: [String], subject: String, message: String, sendEncryptedIfPossible: Bool = true, callback: @escaping (Error?) -> Void, loggingMail: Bool = false, htmlContent: String? = nil, warningReact: Bool = false, inviteMail: Bool = false, textparts: Int = 0) { + if let useraddr = (UserManager.loadUserValue(Attribute.userAddr) as? String) { let session = createSMTPSession() let builder = MCOMessageBuilder() @@ -362,9 +362,9 @@ class MailHandler { } var inviteMailContent: String? = nil if inviteMail { - inviteMailContent = message + inviteMailContent = textparts.description } - Logger.log(sent: fromLogging, to: toLogging, cc: ccLogging, bcc: bccLogging, subject: subject, bodyLength: (String(data: cryptoObject.chiphertext!, encoding: String.Encoding.utf8) ?? "").count, isEncrypted: true, decryptedBodyLength: ("\n" + message).count, decryptedWithOldPrivateKey: false, isSigned: true, isCorrectlySigned: true, signingKeyID: sk.keyID!, myKeyID: sk.keyID!, secureAddresses: secureAddresses, encryptedForKeyIDs: keyIDs, inviteMailContent: inviteMailContent) + Logger.log(sent: fromLogging, to: toLogging, cc: ccLogging, bcc: bccLogging, subject: subject, bodyLength: (String(data: cryptoObject.chiphertext!, encoding: String.Encoding.utf8) ?? "").count, isEncrypted: true, decryptedBodyLength: ("\n" + message).count, decryptedWithOldPrivateKey: false, isSigned: true, isCorrectlySigned: true, signingKeyID: sk.keyID!, myKeyID: sk.keyID!, secureAddresses: secureAddresses, encryptedForKeyIDs: keyIDs, inviteMailContent: inviteMailContent, invitationMail: inviteMail) } // } @@ -379,11 +379,12 @@ class MailHandler { createLoggingSendCopy(sendData: builder.openPGPEncryptedMessageData(withEncryptedData: sendData)) } - if (isHTMLContent == true) { - builder.htmlBody = message - } else { - builder.textBody = message - } + if let html = htmlContent { + builder.htmlBody = html + } else { + builder.textBody = message + } + } else { //TODO do it better callback(NSError(domain: NSCocoaErrorDomain, code: NSPropertyListReadCorruptError, userInfo: nil)) @@ -392,11 +393,11 @@ class MailHandler { if let unenc = ordered[CryptoScheme.UNKNOWN], !loggingMail { if unenc.count > 0 { - if (isHTMLContent == true) { - builder.htmlBody = message - } else { - builder.textBody = message - } + if let html = htmlContent { + builder.htmlBody = html + } else { + builder.textBody = message + } sendData = builder.data() sendOperation = session.sendOperation(with: sendData, from: userID, recipients: unenc) @@ -406,9 +407,9 @@ class MailHandler { // Logger.queue.async(flags: .barrier) { var inviteMailContent: String? = nil if inviteMail { - inviteMailContent = message + inviteMailContent = textparts.description } - Logger.log(sent: fromLogging, to: toLogging, cc: ccLogging, bcc: bccLogging, subject: subject, bodyLength: ("\n" + message).count, isEncrypted: false, decryptedBodyLength: ("\n" + message).count, decryptedWithOldPrivateKey: false, isSigned: false, isCorrectlySigned: false, signingKeyID: "", myKeyID: "", secureAddresses: [], encryptedForKeyIDs: [], inviteMailContent: inviteMailContent) + Logger.log(sent: fromLogging, to: toLogging, cc: ccLogging, bcc: bccLogging, subject: subject, bodyLength: ("\n" + message).count, isEncrypted: false, decryptedBodyLength: ("\n" + message).count, decryptedWithOldPrivateKey: false, isSigned: false, isCorrectlySigned: false, signingKeyID: "", myKeyID: "", secureAddresses: [], encryptedForKeyIDs: [], inviteMailContent: inviteMailContent, invitationMail: inviteMail) // } } sendOperation.start(callback) @@ -771,7 +772,7 @@ class MailHandler { func loadMailsForInbox(newMailCallback: @escaping ((_ mail: PersistentMail?) -> ()), completionCallback: @escaping ((_ error: Bool) -> ())) { let folder = DataHandler.handler.findFolder(with: INBOX) - let folderstatus = IMAPSession.folderStatusOperation(folder.name) + let folderstatus = IMAPSession.folderStatusOperation(folder.path) folderstatus?.start { (error, status) -> Void in guard error == nil else { if self.shouldTryRefreshOAUTH { @@ -966,9 +967,10 @@ class MailHandler { if let m = mail { let pgp = SwiftPGP() if let autoc = autocrypt { - let publickeys = try! pgp.importKeys(key: autoc.key, pw: nil, isSecretKey: false, autocrypt: true) - for pk in publickeys { - _ = DataHandler.handler.newPublicKey(keyID: pk, cryptoType: CryptoScheme.PGP, adr: from.mailbox, autocrypt: true, firstMail: mail) + if let publickeys = try? pgp.importKeys(key: autoc.key, pw: nil, isSecretKey: false, autocrypt: true) { + for pk in publickeys { + _ = DataHandler.handler.newPublicKey(keyID: pk, cryptoType: CryptoScheme.PGP, adr: from.mailbox, autocrypt: true, firstMail: mail) + } } } for keyId in newKeyIds { @@ -1006,19 +1008,22 @@ class MailHandler { let e = end.upperBound let pk = content[s..<e] let pgp = SwiftPGP() - let keyId = try! pgp.importKeys(key: pk, pw: nil, isSecretKey: false, autocrypt: false) - newKey.append(contentsOf: keyId) + if let keyId = try? pgp.importKeys(key: pk, pw: nil, isSecretKey: false, autocrypt: false) { + newKey.append(contentsOf: keyId) + } } } } } else if attachment.mimeType == "application/octet-stream", let content = String(data: attachment.data, encoding: String.Encoding.utf8), content.hasPrefix("-----BEGIN PGP PUBLIC KEY BLOCK-----") && (content.hasSuffix("-----END PGP PUBLIC KEY BLOCK-----") || content.hasSuffix("-----END PGP PUBLIC KEY BLOCK-----\n")) { let pgp = SwiftPGP() - let keyId = try! pgp.importKeys(key: content, pw: nil, isSecretKey: false, autocrypt: false) - newKey.append(contentsOf: keyId) + if let keyId = try? pgp.importKeys(key: content, pw: nil, isSecretKey: false, autocrypt: false) { + newKey.append(contentsOf: keyId) + } } else if attachment.mimeType == "application/pgp-keys" { let pgp = SwiftPGP() - let keyIds = try! pgp.importKeys(data: attachment.data, pw: nil, secret: false) - newKey.append(contentsOf: keyIds) + if let keyIds = try? pgp.importKeys(data: attachment.data, pw: nil, secret: false) { + newKey.append(contentsOf: keyIds) + } } return newKey } @@ -1054,8 +1059,9 @@ class MailHandler { } } if let a = autocrypt { - let key = try! pgp.importKeys(key: a.key, pw: nil, isSecretKey: false, autocrypt: true) - keyIds.append(contentsOf: key) + if let key = try? pgp.importKeys(key: a.key, pw: nil, isSecretKey: false, autocrypt: true) { + keyIds.append(contentsOf: key) + } } let secretkeys = DataHandler.handler.findSecretKeys() var decIds = [String]() @@ -1087,7 +1093,6 @@ class MailHandler { session.authType = UserManager.loadSmtpAuthType() session.connectionType = MCOConnectionType.init(rawValue: UserManager.loadUserValue(Attribute.smtpConnectionType) as! Int) - session.connectionType = MCOConnectionType.startTLS session.checkAccountOperationWith(from: MCOAddress.init(mailbox: useraddr)).start(completion) } @@ -1187,7 +1192,7 @@ class MailHandler { } func updateFolder(folder: Folder, newMailCallback: @escaping ((_ mail: PersistentMail?) -> ()), completionCallback: @escaping ((Bool) -> ())) { - let folderstatus = IMAPSession.folderStatusOperation(folder.name) + let folderstatus = IMAPSession.folderStatusOperation(folder.path) folderstatus?.start { (error, status) -> Void in guard error == nil else { if self.shouldTryRefreshOAUTH { @@ -1207,7 +1212,7 @@ class MailHandler { if let date = folder.lastUpdate { self.loadMailsSinceDate(folder: folder, since: date, newMailCallback: newMailCallback, completionCallback: completionCallback) } else { - if folder.path == UserManager.backendInboxFolderPath || folder.path == "INBOX" || folder.path == "Inbox" { + if folder.path == UserManager.backendInboxFolderPath || folder.path.lowercased() == "INBOX".lowercased() { self.initInbox(inbox: folder, newMailCallback: newMailCallback, completionCallback: completionCallback) } else { self.initFolder(folder: folder, newMailCallback: newMailCallback, completionCallback: completionCallback) diff --git a/enzevalos_iphone/PLists/enzevalos-Info.plist b/enzevalos_iphone/PLists/enzevalos-Info.plist index 6897988ea9107008282c5e0796bf63dc763edb74..06b1bb53f97e86d96ae4c44fcaeadd00585beed0 100644 --- a/enzevalos_iphone/PLists/enzevalos-Info.plist +++ b/enzevalos_iphone/PLists/enzevalos-Info.plist @@ -17,7 +17,7 @@ <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> - <string>0.8.3</string> + <string>0.8.4</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleURLTypes</key> @@ -32,7 +32,7 @@ </dict> </array> <key>CFBundleVersion</key> - <string>0.8.3</string> + <string>0.8.4</string> <key>LSRequiresIPhoneOS</key> <true/> <key>NSAppTransportSecurity</key> diff --git a/enzevalos_iphone/QRScannerView.swift b/enzevalos_iphone/QRScannerView.swift index f00703c48ef1dbf1fd2182adc9b1198ac9ffb57d..363d804d6a4eaec151ae4eaac290189f487bbddb 100644 --- a/enzevalos_iphone/QRScannerView.swift +++ b/enzevalos_iphone/QRScannerView.swift @@ -166,7 +166,7 @@ class QRScannerView: ViewControllerPannable, AVCaptureMetadataOutputObjectsDeleg let alert = UIAlertController(title: NSLocalizedString("fingerprintMissmatchShort", comment: "Found fingerprint does not match"), message: NSLocalizedString("fingerprintMissmatchText", comment: "Found fingerprint does not match"), preferredStyle: .alert) alert.addAction(UIAlertAction(title: NSLocalizedString("MoreInformation", comment: "More Information"), style: .default, handler: { (action: UIAlertAction!) -> Void in - UIApplication.shared.openURL(URL(string: "https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#headingWrongFingerprint")!) + UIApplication.shared.openURL(URL(string: "https://userpage.fu-berlin.de/letterbox/faq.html#headingWrongFingerprint")!) self.dismiss(animated: false, completion: nil) })) alert.addAction(UIAlertAction(title: NSLocalizedString("scanDifferentCode", comment: ""), style: .default, handler: { diff --git a/enzevalos_iphone/ReadViewController.swift b/enzevalos_iphone/ReadViewController.swift index c3f4f8b6c4fc48247a688495578d734fd3dc0e64..094aa61733cfcc6a5b3cc634a71dc1e326250471 100644 --- a/enzevalos_iphone/ReadViewController.swift +++ b/enzevalos_iphone/ReadViewController.swift @@ -326,10 +326,10 @@ class ReadViewController: UITableViewController { let url: String if m.trouble { alert = UIAlertController(title: NSLocalizedString("LetterDamaged", comment: "Modified email received")/*"Angerissener Brief"*/, message: NSLocalizedString("ReceiveDamagedInfo", comment: "Modefied email infotext"), preferredStyle: .alert) - url = "https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#collapseTorn" + url = "https://userpage.fu-berlin.de/letterbox/faq.html#collapseTorn" } else if m.isSecure { alert = UIAlertController(title: NSLocalizedString("Letter", comment: "letter label"), message: NSLocalizedString("ReceiveSecureInfo", comment: "Letter infotext"), preferredStyle: .alert) - url = "https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#secureMailAnswer" + url = "https://userpage.fu-berlin.de/letterbox/faq.html#secureMailAnswer" alert.addAction(UIAlertAction(title: NSLocalizedString("ReadMailOnOtherDevice", comment: "email is not readable on other devices"), style: .default, handler: { (action: UIAlertAction!) -> Void in // Logger.queue.async(flags: .barrier) { Logger.log(close: url, mail: m, action: "exportKey") @@ -338,16 +338,16 @@ class ReadViewController: UITableViewController { })) } else if m.isCorrectlySigned { alert = UIAlertController(title: NSLocalizedString("Postcard", comment: "postcard label"), message: NSLocalizedString("ReceiveInsecureInfoVerified", comment: "Postcard infotext"), preferredStyle: .alert) - url = "https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#collapsePostcard" + url = "https://userpage.fu-berlin.de/letterbox/faq.html#collapsePostcard" } else if m.isEncrypted && !m.unableToDecrypt { alert = UIAlertController(title: NSLocalizedString("Postcard", comment: "postcard label"), message: NSLocalizedString("ReceiveInsecureInfoEncrypted", comment: "Postcard infotext"), preferredStyle: .alert) - url = "https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#collapsePostcard" + url = "https://userpage.fu-berlin.de/letterbox/faq.html#collapsePostcard" } else if m.isEncrypted && m.unableToDecrypt { alert = UIAlertController(title: NSLocalizedString("Postcard", comment: "postcard label"), message: NSLocalizedString("ReceiveInsecureInfoDecryptionFailed", comment: "Postcard infotext"), preferredStyle: .alert) - url = "https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#collapseBeginPGP" + url = "https://userpage.fu-berlin.de/letterbox/faq.html#collapseBeginPGP" } else { alert = UIAlertController(title: NSLocalizedString("Postcard", comment: "postcard label"), message: NSLocalizedString("ReceiveInsecureInfo", comment: "Postcard infotext"), preferredStyle: .alert) - url = "https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#collapsePostcard" + url = "https://userpage.fu-berlin.de/letterbox/faq.html#collapsePostcard" } // Logger.queue.async(flags: .barrier) { Logger.log(open: url, mail: m) diff --git a/enzevalos_iphone/SendViewController+Invitation.swift b/enzevalos_iphone/SendViewController+Invitation.swift index b6ccc97912b3872cfb0f5c160ebaab1a4623d84b..3696c8f013f3fcf24bb08c668ec4d711244f8bc9 100644 --- a/enzevalos_iphone/SendViewController+Invitation.swift +++ b/enzevalos_iphone/SendViewController+Invitation.swift @@ -10,14 +10,6 @@ import UIKit // MARK: - InvitationSelection - -/* - TODO: - Code speichern (pro Kontakt) - Erklärung was genau passiert? - InviteMode == Enc || InviteMode == Censor -> Einladebutton wird zu Infobutton - FreiText -> Popup -> leere E-Mail -*/ struct InvitationSelection { var selectedWords = Set<NSRange>() @@ -35,16 +27,21 @@ extension SendViewController { } } - func htmlMessage() -> String? { - + func htmlMessage() -> (html: String?, textparts: Int, plaintext: String?) { + var htmlName = "invitationText" + if isCensored { + htmlName = "invitationTextCensor" + } guard - let resource = Bundle.main.url(forResource: "invitationText", withExtension: "html"), + let resource = Bundle.main.url(forResource: htmlName, withExtension: "html"), let data = try? Data(contentsOf: resource), let htmlString = String(data: data, encoding: .utf8), (self.isEligibleForInvitation() == true && self.invitationSelection.selectedWords.isEmpty == false) else { - return nil + return (nil, 0, nil) } var text: String = self.textView.text + var plainText: String = self.textView.text + let textsToEncrypt = self.invitationSelection.selectedWords.sorted { (lhs, rhs) -> Bool in return lhs.location < rhs.location }.map { (range) -> String in @@ -54,20 +51,29 @@ extension SendViewController { let texts = textsToEncrypt.map { _ -> String in // Change text in mail body if isCensored{ - return String(repeating: "*", count: (Int(arc4random_uniform(10)+3))) + return String(repeating: "█" as String as String, count: (Int(arc4random_uniform(7)+3))) } return String.random(length: 10) } + + if texts.count > 0 { + if isCensored { + isCensoredMail = true + } + else{ + isPartialEncryptedMail = true + } + } guard let urlTexts = texts.joined(separator: ",").urlString, let cipher = cipherText.chiphers.first?.urlString else { - return nil + return (nil, 0, nil) } - var link = "http://enzevalos.konstantindeichmann.de?text=\(urlTexts)&cipher=\(cipher)" + var link = "http://letterbox.imp.fu-berlin.de?text=\(urlTexts)&cipher=\(cipher)&id=\(StudySettings.studyID)&invitation=Enc" if isCensored{ - link = "https://userpage.fu-berlin.de/wieseoli/letterbox/" + link = "http://letterbox.imp.fu-berlin.de?id=\(StudySettings.studyID)&invitation=Censor" } let locations = self.invitationSelection.selectedWords.sorted { (lhs, rhs) -> Bool in @@ -78,21 +84,39 @@ extension SendViewController { if isCensored{ let t = text as NSString text = t.replacingCharacters(in: range, with: texts[index]) - text = text + NSLocalizedString("Invitation.CensorFooter", comment: "") + plainText = (plainText as NSString).replacingCharacters(in: range, with: texts[index]) } else{ text = (text as NSString).replacingCharacters(in: range, with: "<a class=\"encrypted-text\">\(texts[index])</a>") + plainText = (plainText as NSString).replacingCharacters(in: range, with: texts[index]) + } } if (self.invitationSelection.code == nil && StudySettings.invitationsmode == InvitationMode.PasswordEnc) { self.invitationSelection.code = cipherText.password } - if StudySettings.invitationsmode == InvitationMode.Censorship{ - return text - + var previousText = "" + + if let range = text.range(of: NSLocalizedString("Mail.Signature", comment: "")){ + text.removeSubrange(range) } - return String(format: htmlString, text, link, link) + + if let preMail = prefilledMail, let previousBody = preMail.body{ + if let range = text.range(of: previousBody){ + previousText = previousBody + text.removeSubrange(range) + } + } + + var plainFooter = String(format: NSLocalizedString("Invitation.EncryptionFooter", comment: ""), link, link) + if isCensored { + plainFooter = String(format: NSLocalizedString("Invitation.CensorFooter", comment: ""), link, link) + } + + plainText = plainText + plainFooter + "\n\n" + previousText + + return (String(format: htmlString, text, link, link, previousText), texts.count, nil) } fileprivate func removeAllInvitationMarks() { @@ -113,15 +137,21 @@ extension SendViewController { } guard selectedRange != nil else { - var labelTitel = NSLocalizedString("Invitation.Encrypt", comment: "") - if StudySettings.invitationsmode == InvitationMode.Censorship{ - labelTitel = NSLocalizedString("Invitation.Encrypt.Censor", comment: "") + let labelTitel: String + switch StudySettings.invitationsmode { + case .Censorship : labelTitel = NSLocalizedString("Invitation.Encrypt.Censor", comment: "") + case .PasswordEnc : labelTitel = NSLocalizedString("Invitation.Encrypt", comment: "") + case .FreeText, + .InviteMail : return nil } return [UIMenuItem(title: labelTitel, action: #selector(self.markSelectedText))] } - var labelTitel = NSLocalizedString("Invitation.Decrypt", comment: "") - if StudySettings.invitationsmode == InvitationMode.Censorship{ - labelTitel = NSLocalizedString("Invitation.Decrypt.Censor", comment: "") + let labelTitel: String + switch StudySettings.invitationsmode { + case .Censorship : labelTitel = NSLocalizedString("Invitation.Decrypt.Censor", comment: "") + case .PasswordEnc : labelTitel = NSLocalizedString("Invitation.Decrypt", comment: "") + case .FreeText, + .InviteMail : return nil } return [UIMenuItem(title: labelTitel, action: #selector(self.unmarkSelectedText))] } @@ -184,7 +214,7 @@ extension SendViewController { func showFirstDialogIfNeeded() { - guard (self.isEligibleForInvitation() == true && self.invitationSelection.didShowDialog == false && InvitationUserDefaults.shouldNotShowFirstDialog.bool == false) else { + guard (self.isEligibleForInvitation() == true && self.invitationSelection.didShowDialog == false && InvitationUserDefaults.shouldNotShowFirstDialog.bool == false && invite == false) else { return } @@ -192,8 +222,19 @@ extension SendViewController { let controller = DialogViewController.present(on: self, with: .invitationWelcome) { [weak self] in self?.view.endEditing(true) } + controller?.ctaAction = { controller?.hideDialog(completion: nil) + switch StudySettings.invitationsmode { + case .FreeText: + self.performSegue(withIdentifier: "inviteSegueStudy", sender: nil) + return + case .InviteMail: + self.performSegue(withIdentifier: "inviteSegue", sender: nil) + return + case .Censorship, .PasswordEnc: + return + } } controller?.dismissAction = { @@ -210,6 +251,7 @@ extension SendViewController { self.view.endEditing(true) InvitationUserDefaults.shouldNotShowSecondDialog.set(true) let controller = DialogViewController.present(on: self, with: .invitationStep) + controller?.ctaAction = { controller?.hideDialog(completion: nil) } @@ -219,6 +261,14 @@ extension SendViewController { self?.layoutText() } } + + func showHelpDialog() { + let controller = DialogViewController.present(on: self, with: .invitationHelp) + + controller?.ctaAction = { + controller?.hideDialog(completion: nil) + } + } } // MARK: - MarkHandler diff --git a/enzevalos_iphone/SendViewController.swift b/enzevalos_iphone/SendViewController.swift index 0550f72248e3882c99289d2f81921eff1503251d..ca90f9f2c3a6e0dbd25cf90480c82292ffbcc388 100644 --- a/enzevalos_iphone/SendViewController.swift +++ b/enzevalos_iphone/SendViewController.swift @@ -39,7 +39,7 @@ class SendViewController: UIViewController { @IBOutlet weak var scrollViewBottom: NSLayoutConstraint! @IBOutlet var scrollviewRecognizer: UITapGestureRecognizer! @IBOutlet weak var sendButton: UIBarButtonItem! - + var keyboardOpened = false var keyboardY: CGFloat = 0 var keyboardHeight: CGFloat = 0 @@ -56,28 +56,45 @@ class SendViewController: UIViewController { var sendEncryptedIfPossible = true var freeTextInviationTitle = StudySettings.freeTextInvitationTitle var freeTextInvitationCall: (() -> (String)) = StudySettings.freeTextInvitationCode - var invite:Bool = false + var invite: Bool = false + var isCensoredMail: Bool = false + var isPartialEncryptedMail: Bool = false + + var sendInProgress: Bool = false { + didSet { + if sendInProgress { + self.view.endEditing(true) + } + sendButton.isEnabled = !sendInProgress + textView.isEditable = !sendInProgress + subjectText.isEnabled = !sendInProgress + toText.isEnabled = !sendInProgress + ccText.isEnabled = !sendInProgress + } + } - var invitationSelection = InvitationSelection() + var invitationSelection = InvitationSelection() - var toSecure = true { - didSet { - self.updateMarkedText(for: self.textView) - self.showFirstDialogIfNeeded() - } - } + var toSecure = true { + didSet { + self.updateMarkedText(for: self.textView) + self.showFirstDialogIfNeeded() + } + } override func viewDidLoad() { super.viewDidLoad() - + dataDelegate = VENDataDelegate(changeFunc: self.editName, tappedWhenSelectedFunc: self.showContact, beginFunc: self.beginEditing, endFunc: self.endEditing, deleteFunc: { () -> Void in return }) tableDataDelegate = TableViewDataDelegate(insertCallback: self.insertName) collectionDataDelegate = CollectionDataDelegate(suggestionFunc: AddressHandler.frequentAddresses, insertCallback: self.insertName) startIconAnimation() textView.font = UIFont.systemFont(ofSize: 17) - textView.text = "" - textView.delegate = self + if textView.text.count == 0 { + textView.text.append(NSLocalizedString("Mail.Signature", comment: "")) + } + textView.delegate = self subjectText.toLabelText = NSLocalizedString("Subject", comment: "subject label") + ": " @@ -129,7 +146,12 @@ class SendViewController: UIViewController { } subjectText.setText(prefilledMail.subject ?? "") - textView.text.append(prefilledMail.body ?? "") + if invite && prefilledMail.body != nil{ + textView.text = "" + textView.text.append(prefilledMail.body!) + } else { + textView.text.append(prefilledMail.body ?? "") + } } let sepConst: CGFloat = 1 / UIScreen.main.scale @@ -150,7 +172,7 @@ class SendViewController: UIViewController { tableview.dataSource = tableDataDelegate tableview.register(UINib(nibName: "ContactCell", bundle: nil), forCellReuseIdentifier: "contacts") tableviewHeight.constant = 0 - + let indexPath = IndexPath() tableview.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic) @@ -170,9 +192,9 @@ class SendViewController: UIViewController { updateNavigationBar() sendEncryptedIfPossible = currentSecurityState - + // Logger.queue.async(flags: .barrier) { - Logger.log(sendViewOpen: prefilledMail) + Logger.log(sendViewOpen: prefilledMail) // } } @@ -181,18 +203,18 @@ class SendViewController: UIViewController { } override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) + super.viewWillAppear(animated) updateNavigationBar() } override func viewWillDisappear(_ animated: Bool) { // Logger.queue.async(flags: .barrier) { - Logger.log(sendViewClose: prefilledMail) + Logger.log(sendViewClose: prefilledMail) // } super.viewWillDisappear(animated) } - + override func willMove(toParentViewController parent: UIViewController?) { super.willMove(toParentViewController: parent) @@ -215,10 +237,9 @@ class SendViewController: UIViewController { self.ccCollectionview.reloadData() self.ccCollectionviewHeight.constant = 100 self.ccCollectionview.isHidden = false - } - else { - self.ccCollectionviewHeight.constant = 1 - self.ccCollectionview.isHidden = true + } else { + self.ccCollectionviewHeight.constant = 1 + self.ccCollectionview.isHidden = true } } if self.toText.isFirstResponder { @@ -226,16 +247,14 @@ class SendViewController: UIViewController { self.toCollectionview.reloadData() self.toCollectionviewHeight.constant = 100 self.toCollectionview.isHidden = false - } - else { - self.toCollectionviewHeight.constant = 1 - self.toCollectionview.isHidden = true + } else { + self.toCollectionviewHeight.constant = 1 + self.toCollectionview.isHidden = true } } - + self.toCollectionview.reloadData() self.ccCollectionview.reloadData() - } } @@ -278,7 +297,8 @@ class SendViewController: UIViewController { } } - let mail = EphemeralMail(to: NSSet.init(array: to), cc: NSSet.init(array: cc), bcc: NSSet.init(), date: Date(), subject: NSLocalizedString("inviteSubject", comment: "Subject for the invitation mail"), body: NSLocalizedString("inviteText", comment: "Body for the invitation mail"), uid: 0, predecessor: nil) + let body = String(format: NSLocalizedString("inviteText", comment: "Body for the invitation mail"),StudySettings.studyID) + let mail = EphemeralMail(to: NSSet.init(array: to), cc: NSSet.init(array: cc), bcc: NSSet.init(), date: Date(), subject: NSLocalizedString("inviteSubject", comment: "Subject for the invitation mail"), body: body, uid: 0, predecessor: nil) controller.prefilledMail = mail @@ -287,6 +307,7 @@ class SendViewController: UIViewController { let navigationController = segue.destination as? UINavigationController if let controller = navigationController?.topViewController as? SendViewController { controller.invite = true + var to = [MailAddress]() var cc = [MailAddress]() for mail in toText.mailTokens { @@ -299,16 +320,17 @@ class SendViewController: UIViewController { cc.append(DataHandler.handler.getMailAddress(mail, temporary: false)) } } - - let mail = EphemeralMail(to: NSSet.init(array: to), cc: NSSet.init(array: cc), bcc: NSSet.init(), date: Date(), subject: NSLocalizedString("inviteSubject", comment: "Subject for the invitation mail"), body: "", uid: 0, predecessor: nil) - - + + let mail = EphemeralMail(to: NSSet.init(array: to), cc: NSSet.init(array: cc), bcc: NSSet.init(), date: Date(), subject: NSLocalizedString("inviteSubject", comment: "Subject for the invitation mail"), body: "\n\nMehr Informationen unter https://userpage.fu-berlin.de/letterbox/", uid: 0, predecessor: nil) + + controller.prefilledMail = mail - let alert = UIAlertController(title: "abc", message: "xyz", preferredStyle: .alert) //TODO: @Olli add your Text here - alert.addAction(UIAlertAction(title: "OK", style: .cancel)) - DispatchQueue.main.async(execute: { - controller.present(alert, animated: true, completion: nil) - }) + +// let alert = UIAlertController(title: "abc", message: "xyz", preferredStyle: .alert) //TODO: @Olli add your Text here +// alert.addAction(UIAlertAction(title: "OK", style: .cancel)) +// DispatchQueue.main.async(execute: { +// controller.present(alert, animated: true, completion: nil) +// }) } } } @@ -339,40 +361,38 @@ class SendViewController: UIViewController { func beginEditing(_ tokenField: VENTokenField) { UIView.animate(withDuration: 0.25, delay: 0, options: UIViewAnimationOptions(rawValue: 7), animations: { - if tokenField == self.toText { - if self.collectionDataDelegate.collectionView(self.toCollectionview, numberOfItemsInSection: 0) > 0 { - self.toCollectionview.reloadData() - self.toCollectionviewHeight.constant = 100 - self.toCollectionview.isHidden = false - } - else { + if tokenField == self.toText { + if self.collectionDataDelegate.collectionView(self.toCollectionview, numberOfItemsInSection: 0) > 0 { + self.toCollectionview.reloadData() + self.toCollectionviewHeight.constant = 100 + self.toCollectionview.isHidden = false + } else { self.toCollectionviewHeight.constant = 1 self.toCollectionview.isHidden = true - } - } else if tokenField == self.ccText { - if self.collectionDataDelegate.collectionView(self.ccCollectionview, numberOfItemsInSection: 0) > 0 { - self.ccCollectionview.reloadData() - self.ccCollectionviewHeight.constant = 100 - self.ccCollectionview.isHidden = false - } - else { + } + } else if tokenField == self.ccText { + if self.collectionDataDelegate.collectionView(self.ccCollectionview, numberOfItemsInSection: 0) > 0 { + self.ccCollectionview.reloadData() + self.ccCollectionviewHeight.constant = 100 + self.ccCollectionview.isHidden = false + } else { self.ccCollectionviewHeight.constant = 1 self.ccCollectionview.isHidden = true + } } - } self.view.layoutIfNeeded() }, completion: nil) } func endEditing(_ tokenField: VENTokenField) { UIView.animate(withDuration: 0.25, delay: 0, options: UIViewAnimationOptions(rawValue: 7), animations: { - if tokenField == self.toText { - self.toCollectionviewHeight.constant = 1 - self.toCollectionview.isHidden = true - } else if tokenField == self.ccText { - self.ccCollectionviewHeight.constant = 1 - self.ccCollectionview.isHidden = true - } + if tokenField == self.toText { + self.toCollectionviewHeight.constant = 1 + self.toCollectionview.isHidden = true + } else if tokenField == self.ccText { + self.ccCollectionviewHeight.constant = 1 + self.ccCollectionview.isHidden = true + } self.view.layoutIfNeeded() }, completion: nil) } @@ -427,39 +447,38 @@ class SendViewController: UIViewController { let animationCurveRawNSN = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue let animationCurve = UIViewAnimationOptions(rawValue: animationCurveRaw) - + if #available(iOS 11.0, *) { - + guard let userInfo = notification.userInfo, let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return } - + let keyboardFrameInView = view.convert(keyboardFrame, from: nil) let safeAreaFrame = view.safeAreaLayoutGuide.layoutFrame.insetBy(dx: 0, dy: -additionalSafeAreaInsets.bottom) let intersection = safeAreaFrame.intersection(keyboardFrameInView) - + let animationDuration: TimeInterval = (notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0 let animationCurveRawNSN = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue let animationCurve = UIViewAnimationOptions(rawValue: animationCurveRaw) - + self.keyboardY = keyboardFrameInView.minY - + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { self.additionalSafeAreaInsets.bottom = intersection.height let desiredOffset = CGPoint(x: 0, y: 0) self.scrollview.setContentOffset(desiredOffset, animated: false) self.view.layoutIfNeeded() }, completion: nil) - } - else { + } else { var info = notification.userInfo! let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue keyboardY = keyboardFrame.origin.y if keyboardHeight == 0 { keyboardHeight = keyboardFrame.height - + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { self.scrollViewBottom.constant -= self.keyboardHeight let desiredOffset = CGPoint(x: 0, y: -self.keyboardHeight) @@ -468,8 +487,8 @@ class SendViewController: UIViewController { }, completion: nil) } else { UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { - self.scrollViewBottom.constant += (self.keyboardHeight-keyboardFrame.height) - let desiredOffset = CGPoint(x: 0, y: +(self.keyboardHeight-keyboardFrame.height)) + self.scrollViewBottom.constant += (self.keyboardHeight - keyboardFrame.height) + let desiredOffset = CGPoint(x: 0, y: +(self.keyboardHeight - keyboardFrame.height)) self.keyboardHeight = keyboardFrame.height self.scrollview.setContentOffset(desiredOffset, animated: false) self.view.layoutIfNeeded() @@ -477,37 +496,36 @@ class SendViewController: UIViewController { } } } - + func keyboardClose(_ notification: Notification) { let animationDuration: TimeInterval = (notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0 let animationCurveRawNSN = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue let animationCurve = UIViewAnimationOptions(rawValue: animationCurveRaw) - + if #available(iOS 11.0, *) { - + guard let userInfo = notification.userInfo, let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return } - + let keyboardFrameInView = view.convert(keyboardFrame, from: nil) let safeAreaFrame = view.safeAreaLayoutGuide.layoutFrame.insetBy(dx: 0, dy: -additionalSafeAreaInsets.bottom) let intersection = safeAreaFrame.intersection(keyboardFrameInView) - + self.keyboardY = 0 - + let animationDuration: TimeInterval = (notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0 let animationCurveRawNSN = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue let animationCurve = UIViewAnimationOptions(rawValue: animationCurveRaw) - + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { self.additionalSafeAreaInsets.bottom = intersection.height self.view.layoutIfNeeded() }, completion: nil) - } - else { + } else { UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { self.scrollViewBottom.constant += self.keyboardHeight self.keyboardY = 0 @@ -530,7 +548,7 @@ class SendViewController: UIViewController { let alert = UIAlertController(title: NSLocalizedString("ReceiveError", comment: "There was an error"), message: NSLocalizedString("ErrorText", comment: ""), preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: NSLocalizedString("Done", comment: ""), style: UIAlertActionStyle.default, handler: nil)) self.present(alert, animated: true, completion: nil) - sendButton.isEnabled = true + sendInProgress = false } else { NSLog("Send successful!") if (self.prefilledMail != nil) { @@ -538,27 +556,27 @@ class SendViewController: UIViewController { self.prefilledMail?.predecessor?.isAnwered = true } } - sendButton.isEnabled = true + sendInProgress = false self.sendCompleted() } } func sendCompleted() { - guard let code = self.invitationSelection.code, self.htmlMessage() != nil else { - self.navigationController?.dismiss(animated: true, completion: nil) - return - } + guard let code = self.invitationSelection.code, isPartialEncryptedMail else { + self.navigationController?.dismiss(animated: true, completion: nil) + return + } - let controller = DialogViewController.present(on: self, with: .invitationCode(code: code)) - controller?.ctaAction = { - let activityController = UIActivityViewController(activityItems: [code], applicationActivities: nil) - controller?.present(activityController, animated: true, completion: nil) - controller?.markDismissButton(with: .invitationCode(code: code)) - } + let controller = DialogViewController.present(on: self, with: .invitationCode(code: code)) + controller?.ctaAction = { + let activityController = UIActivityViewController(activityItems: [code], applicationActivities: nil) + controller?.present(activityController, animated: true, completion: nil) + controller?.markDismissButton(with: .invitationCode(code: code)) + } - controller?.dismissAction = { [weak self] in - self?.dismiss(animated: true, completion: nil) - } + controller?.dismissAction = { [weak self] in + self?.dismiss(animated: true, completion: nil) + } } @@ -568,10 +586,10 @@ class SendViewController: UIViewController { guard let toSource = toText.dataSource, let ccSource = ccText.dataSource else { return true } - + toSecure = toSource.allSecure(toText) ccSecure = ccSource.allSecure(ccText) - + return toSecure && ccSecure } @@ -590,10 +608,10 @@ class SendViewController: UIViewController { guard let toSource = toText.dataSource, let ccSource = ccText.dataSource else { return true } - + let toKey = toSource.someInsecure(toText) let ccKey = ccSource.someInsecure(ccText) - + return toKey || ccKey } @@ -635,53 +653,50 @@ class SendViewController: UIViewController { let url: String if !UISecurityState { alert = UIAlertController(title: NSLocalizedString("Postcard", comment: "Postcard label"), message: sendEncryptedIfPossible ? NSLocalizedString("SendInsecureInfo", comment: "Postcard infotext") : NSLocalizedString("SendInsecureInfoAll", comment: "Postcard infotext"), preferredStyle: .alert) - url = "https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#headingPostcard" + url = "https://userpage.fu-berlin.de/letterbox/faq.html#headingPostcard" if subjectText.inputText() != NSLocalizedString("inviteSubject", comment: "") && !currentSecurityState && !UserDefaults.standard.bool(forKey: "hideFreeTextInvitation") { alert.addAction(UIAlertAction(title: freeTextInviationTitle, style: .default, handler: { (action: UIAlertAction) -> Void in - let segue = self.freeTextInvitationCall() -// Logger.queue.async(flags: .barrier) { - Logger.log(close: url, mail: nil, action: segue) -// } - self.performSegue(withIdentifier: segue, sender: nil) + switch StudySettings.invitationsmode { + case .InviteMail: + self.performSegue(withIdentifier: "inviteSegue", sender: nil) + case .FreeText: + self.performSegue(withIdentifier: "inviteSegueStudy", sender: nil) + case .Censorship, .PasswordEnc: + DispatchQueue.main.async { + self.showHelpDialog() + } + } + + Logger.log(close: url, mail: nil, action: "invitationButton in mode \(StudySettings.invitationsmode)") })) } } else { alert = UIAlertController(title: NSLocalizedString("Letter", comment: "Letter label"), message: NSLocalizedString("SendSecureInfo", comment: "Letter infotext"), preferredStyle: .alert) - url = "https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html#secureMail" + url = "https://userpage.fu-berlin.de/letterbox/faq.html#secureMail" } if someoneWithKeyPresent { if sendEncryptedIfPossible { alert.addAction(UIAlertAction(title: someoneWithoutKeyPresent ? NSLocalizedString("sendInsecureAll", comment: "This mail should be send insecurely to everyone, including contacts with keys") : NSLocalizedString("sendInsecure", comment: "This mail should be send insecurely"), style: .default, handler: { (action: UIAlertAction!) -> Void in -// Logger.queue.async(flags: .barrier) { - Logger.log(close: url, mail: nil, action: "sendInsecure") -// } + Logger.log(close: url, mail: nil, action: "sendInsecure") self.sendEncryptedIfPossible = false DispatchQueue.main.async { self.animateIfNeeded() } })) } else { alert.addAction(UIAlertAction(title: someoneWithoutKeyPresent ? NSLocalizedString("sendSecureIfPossible", comment: "This mail should be send securely to people with keys") : NSLocalizedString("sendSecure", comment: "This mail should be send securely"), style: .default, handler: { (action: UIAlertAction!) -> Void in -// Logger.queue.async(flags: .barrier) { - Logger.log(close: url, mail: nil, action: "sendSecureIfPossible") -// } + Logger.log(close: url, mail: nil, action: "sendSecureIfPossible") self.sendEncryptedIfPossible = true DispatchQueue.main.async { self.animateIfNeeded() } })) } } -// Logger.queue.async(flags: .barrier) { - Logger.log(open: url, mail: nil) -// } + Logger.log(open: url, mail: nil) alert.addAction(UIAlertAction(title: NSLocalizedString("MoreInformation", comment: "More Information label"), style: .default, handler: { (action: UIAlertAction!) -> Void in -// Logger.queue.async(flags: .barrier) { - Logger.log(close: url, mail: nil, action: "openURL") -// } + Logger.log(close: url, mail: nil, action: "openURL") UIApplication.shared.openURL(URL(string: url)!) })) alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: { (action: UIAlertAction!) -> Void in -// Logger.queue.async(flags: .barrier) { - Logger.log(close: url, mail: nil, action: "OK") -// } + Logger.log(close: url, mail: nil, action: "OK") })) DispatchQueue.main.async(execute: { self.present(alert, animated: true, completion: nil) @@ -734,26 +749,32 @@ class SendViewController: UIViewController { } @IBAction func pressSend(_ sender: AnyObject?) { + sendInProgress = true + let toEntrys = toText.mailTokens let ccEntrys = ccText.mailTokens let subject = subjectText.inputText()! - let message: String = (self.htmlMessage() ?? self.textView.text) + let (hmtlmessage, counterTextparts, plaintext) = self.htmlMessage() + let message: String = (plaintext ?? self.textView.text) - if invite{ - for addr in toEntrys{ - if let mailAddr = DataHandler.handler.findMailAddress(adr: addr as! String){ + if isCensoredMail || isPartialEncryptedMail{ + invite = true + } + + if invite { + for addr in toEntrys { + if let mailAddr = DataHandler.handler.findMailAddress(adr: addr as! String) { mailAddr.invitations = mailAddr.invitations + 1 } } - for addr in ccEntrys{ - if let mailAddr = DataHandler.handler.findMailAddress(adr: addr as! String){ + for addr in ccEntrys { + if let mailAddr = DataHandler.handler.findMailAddress(adr: addr as! String) { mailAddr.invitations = mailAddr.invitations + 1 } } DataHandler.handler.save(during: "invite") } - mailHandler.send(toEntrys as NSArray as! [String], ccEntrys: ccEntrys as NSArray as! [String], bccEntrys: [], subject: subject, message: message, sendEncryptedIfPossible: sendEncryptedIfPossible, callback: self.mailSend, isHTMLContent: (self.htmlMessage() != nil), inviteMail: true) - sendButton.isEnabled = false + mailHandler.send(toEntrys as NSArray as! [String], ccEntrys: ccEntrys as NSArray as! [String], bccEntrys: [], subject: subject, message: message, sendEncryptedIfPossible: sendEncryptedIfPossible, callback: self.mailSend, htmlContent: hmtlmessage, inviteMail: invite, textparts: counterTextparts) } } @@ -764,7 +785,7 @@ extension SendViewController: UIGestureRecognizerDelegate { } return false } - + @IBAction func tapped(_ sender: UITapGestureRecognizer) { if let view = sender.view, view == scrollview, sender.location(in: view).y >= textView.frame.minY { textView.becomeFirstResponder() @@ -782,17 +803,17 @@ extension VENTokenFieldDataSource { return false } - + func someInsecure(_ tokenField: VENTokenField) -> Bool { for entry in tokenField.mailTokens { if !DataHandler.handler.hasKey(adr: entry as! String) { return true } } - + return false } - + /** Returns a bool showing whether all contacts in the field have a key. Returns true if no contacts are present. */ @@ -802,7 +823,7 @@ extension VENTokenFieldDataSource { return false } } - + return true } } diff --git a/enzevalos_iphone/StudySettings.swift b/enzevalos_iphone/StudySettings.swift index 5aaea95e14e0e35b7320b18783c3928c12fe8f82..df15c017387bba46a73927ca1e333bdb0dd7e2fa 100644 --- a/enzevalos_iphone/StudySettings.swift +++ b/enzevalos_iphone/StudySettings.swift @@ -19,12 +19,12 @@ enum StudyParamter: Int { case .Warning: return "warning" case .Invitation: - return "invitation" + return "invitation" } } } - var fileDir: String { + var keyName: String { get{ switch self { case .Warning: @@ -34,23 +34,23 @@ enum StudyParamter: Int { } } } - var variables: Int { + var numberOfTreatments: UInt32 { get{ switch self { case .Warning: return 2 case .Invitation: - return 4 + return 3 } } } } enum InvitationMode: Int { - case FreeText = 0 - case InviteMail = 1 - case PasswordEnc = 2 - case Censorship = 3 + case InviteMail + case PasswordEnc + case Censorship + case FreeText } class StudySettings { @@ -59,20 +59,29 @@ class StudySettings { static let parameters = [StudyParamter.Invitation] public static var invitationEnabled: Bool{ - get{ - return invitationsmode == InvitationMode.Censorship || invitationsmode == InvitationMode.PasswordEnc + get { + return true //invitationsmode == InvitationMode.Censorship || invitationsmode == InvitationMode.PasswordEnc + } + } + static var freeTextInvitationTitle: String { + get { + switch self.invitationsmode { + case .FreeText, .InviteMail: + return NSLocalizedString("inviteContacts", comment: "Allows users to invite contacts without encryption key") + case .Censorship, .PasswordEnc: + return NSLocalizedString("inviteContacts.Censor", comment: "Allows users to invite contacts without encryption key") + } } } - static var freeTextInvitationTitle = NSLocalizedString("inviteContacts", comment: "Allows users to invite contacts without encryption key") static var freeTextInvitationCode: (() -> (String)) = {Void in return "inviteSegueStudy"/*use "inviteSegue" if there is no study present*/ } //return segue id to perform - static let faqURL = "https://userpage.fu-berlin.de/wieseoli/letterbox/faq.html" + static let faqURL = "https://userpage.fu-berlin.de/letterbox/faq.html" static let raffleURL = "" static var studyID: String { return UserDefaults.standard.string(forKey: "studyID") ?? "" } - static var entrySurveyURL: String{ - get{ - return "https://userpage.fu-berlin.de/wieseoli/letterbox/entrysurvey.html?id=\(studyID)" + static var entrySurveyURL: String { + get { + return "https://userpage.fu-berlin.de/letterbox/entrysurvey.html?id=\(studyID)" } } static var bitcoinMails: Bool { //do we recived a mail from bitcoin.de @@ -93,8 +102,7 @@ class StudySettings { static var invitationsmode: InvitationMode{ get{ - return InvitationMode.Censorship - let value = UserDefaults.standard.integer(forKey: StudyParamter.Invitation.fileDir) + let value = UserDefaults.standard.integer(forKey: StudyParamter.Invitation.keyName) if let mode = InvitationMode.init(rawValue: value){ return mode } @@ -109,21 +117,16 @@ class StudySettings { var studyParamters = [StudyParamter: Int]() for parameter in parameters{ var value: Int? - if let state = keychain[parameter.fileDir], let num = Int(state) { + if let state = keychain[parameter.keyName], let num = Int(state) { value = num - } - else { - value = Int(arc4random_uniform(UInt32(parameter.variables))) + } else { + value = Int(arc4random_uniform(parameter.numberOfTreatments)) if let value = value{ - keychain[parameter.fileDir] = String(value) + keychain[parameter.keyName] = String(value) } } - if parameter == StudyParamter.Invitation{ - //TODO: Remove @Olli - value = InvitationMode.Censorship.rawValue - } if let v = value{ - UserDefaults.standard.set(v, forKey: parameter.fileDir) + UserDefaults.standard.set(v, forKey: parameter.keyName) studyParamters[parameter] = v } } @@ -160,7 +163,6 @@ class StudySettings { } let parameters = studyParameters - //TODO: @Olli set entry "hideFreeTextInvitation" in UserDefaults to true if needed // Logger.queue.async(flags: .barrier) { Logger.log(setupStudy: parameters, alreadyRegistered: !presentFirstQuestionaireMail, bitcoin: bitcoinMails) @@ -179,17 +181,17 @@ class StudySettings { Herzlichen Glückwunsch! Sie haben Letterbox erfolgreich installiert. - Wir haben einen Eingangsfragebogen mit maximal 10 Fragen über Ihre bisherigen Erfahrungen mit E-Mail-Verschlüsselung vorbereitet und würden Sie bitten diesen auszufüllen. - Dazu folgen Sie bitte folgendem Link: - \(entrySurveyURL) - Wenn Sie Fragen zur App oder Verschlüsselung haben, besuchen Sie doch unsere Hilfeseite: \(faqURL) Dort finden Sie auch Videos zum Thema Ende-zu-Ende-Verschlüsselung. Falls Sie Fragen haben oder uns Feedback geben möchten, freuen wir uns auf Ihre E-Mail! - Verfassen Sie doch einen ersten Brief, indem Sie auf diese E-Mail antworten und uns Ihre Erfahrungen, Fragen oder Kommentare mitteilen. Ist etwas unklar geblieben? Was war Ihnen neu? Hätten Sie sich sonst noch etwas gewünscht? + Die Studie umfasst drei Aufgaben und kann jederzeit abgebrochen werden. Für Fragen schreiben Sie uns bitte eine E-Mail und benutzen Sie bitte nach Möglichkeit die Letterbox dafür. + + In der ersten Aufgabe verfassen Sie bitte einen ersten Brief, indem Sie auf diese E-Mail antworten. Bitte teilen Sie uns Ihre Meinung mit. Ist etwas unklar geblieben? Was war neu für Sie? Was fanden Sie besonders interessant; was uninteressant? Hätten Sie sich noch weitere Informationen gewünscht? Sie können auch gerne Fragen zur Einführung stellen. + + Nach Beantwortung dieser E-Mail senden wir Ihnen zu einem späteren Zeitpunkt eine zweite E-Mail mit der nächsten kurzen Aufgabe zu. Vielen Dank für Ihre Teilnahme und mit freundlichen Grüßen, Ihr Letterbox-Team diff --git a/enzevalos_iphone/de.lproj/Localizable.strings b/enzevalos_iphone/de.lproj/Localizable.strings index f1d7d4c25be00cd2f2b1e8a80ffb4d0f19c76e56..1e9bf5dfe90dbfad396d6c406aac1314c8f3d503 100644 --- a/enzevalos_iphone/de.lproj/Localizable.strings +++ b/enzevalos_iphone/de.lproj/Localizable.strings @@ -67,7 +67,7 @@ "LetterDescription" = "• Briefe wurden tatsächlich vom angegebenen Absender versendet\n• Nur Empfänger und Sender können die Nachricht lesen.\n• Für eine sichere Kommunikation müssen alle zusammenarbeiten. Dafür können in der App Kontakte eingeladen werden."; "mail from" = "Nachricht von"; "Message" = "Nachricht"; -"MoreInformation" = "Mehr Informationen"; +"MoreInformation" = "Weitere Informationen"; "Next" = "Weiter"; "next" = "weiter"; "None" = "Keine"; @@ -85,7 +85,7 @@ "ReadOnOtherDevices" = "Briefe auf anderen Geräten lesen!"; "Receive" = "Empfangen"; "ReceiveError" = "Ein Fehler ist aufgetreten"; //mehr spezifizieren? -"ReceiveDamagedInfo" = "Mit dieser Nachricht stimmt was nicht. Der Inhalt könnte kompromitiert oder manipuliert sein."; +"ReceiveDamagedInfo" = "Mit dieser Nachricht stimmt was nicht. Der Inhalt könnte kompromittiert oder manipuliert sein."; "ReceiveSecureInfo" = "Diese Nachricht war ordnungsgemäß verschlossen. Sie kann nicht von Dritten gelesen werden. Die Identität des Absenders wurde bestätigt"; "ReceiveInsecureInfo" = "Diese Nachricht wurde unverschlüsselt gesendet und konnte somit von Allen auf dem Weg mitgelesen werden. Die Identität des Absenders konnte nicht bestätigt werden und der Inhalt könnte manipuliert sein."; "ReceiveInsecureInfoVerified" = "Diese Nachricht wurde unverschlüsselt gesendet und konnte somit von Allen auf dem Weg mitgelesen werden. Die Identität des Absenders wurde bestätigt und die Nachricht wurde nicht verändert."; @@ -97,8 +97,8 @@ "Secure" = "Sicher"; "Send" = "Senden"; "SendError" = "Ein Fehler ist aufgetreten"; //mehr spezifizieren? -"SendInsecureInfo" = "Diese Nachricht würde unsicher an alle orange eingefärbten Kontakte gesendet werden. Somit kann sie unterwegs von anderen gelesen oder manipuliert werden. Du könntest die orangen Kontakte einladen Enzavalos zu verwenden, um sicher mit ihnen zu kommunizieren."; //anstatt unterwegs: auf ihrem Weg -"SendInsecureInfoAll" = "Diese Nachricht würde unsicher an alle Kontakte gesendet werden. Somit kann sie unterwegs von anderen gelesen oder manipuliert werden. Du könntest die orangen Kontakte einladen Enzavalos zu verwenden, um sicher mit ihnen zu kommunizieren."; //anstatt unterwegs: auf ihrem Weg +"SendInsecureInfo" = "Diese Nachricht würde unsicher an alle orange eingefärbten Kontakte gesendet werden. Somit kann sie unterwegs von anderen gelesen oder manipuliert werden. Du könntest die orangen Kontakte einladen Letterbox zu verwenden, um sicher mit ihnen zu kommunizieren."; //anstatt unterwegs: auf ihrem Weg +"SendInsecureInfoAll" = "Diese Nachricht würde unsicher an alle Kontakte gesendet werden. Somit kann sie unterwegs von anderen gelesen oder manipuliert werden. Du könntest die orangen Kontakte einladen Letterbox zu verwenden, um sicher mit ihnen zu kommunizieren."; //anstatt unterwegs: auf ihrem Weg "SendSecureInfo" = "Super! Diese Nachricht würde sicher versendet werden. Somit ist ihr Inhalt vor neugierigen Augen geschützt und kann nicht manipuliert werden."; "SendSuccess" = "Erfolgreich gesendet"; "Sent" = "Gesendet"; @@ -149,8 +149,9 @@ "newKeyHeadline" = "Neues Schloss"; "newKeyText" = "Diese Nachricht wurde mit einem neuem Schloss verbunden. Dies kann passieren wenn der Gesprächspartner ein neues Gerät hat oder wenn ein Dritter diese Nachricht gefälscht hat."; "inviteContacts" = "Unsichere Kontakte einladen"; +"inviteContacts.Censor" = "Erklärungsdialog anzeigen"; "inviteSubject" = "Lass uns unsere E-Mails verschlüsseln!"; -"inviteText" = "Hallo!\n\nEs gibt eine neue App die es super einfach macht verschlüsselt über E-Mail zu kommunizieren. Sie heißt Letterbox und wird aktuell in einer wissenschaftlichen Studie getestet.\n\nEs wäre toll wenn du sie mal ausprobieren würdest!\n\nGehe einfach auf https://userpage.fu-berlin.de/wieseoli/letterbox um mitzumachen.\n\nViele Grüße!"; +"inviteText" = "Hallo, \n\nbisher waren unsere E-Mails immer wie Postkarten und die E-Mail-Provider konnten immer mitlesen. Davor schützt Ende-Zu-Ende-Verschlüsselung. Ich probiere gerade Letterbox aus, aber es gibt auch andere Programme. Letterbox ist besonders einfach und unkompliziert. Wollen wir es mal gemeinsam ausprobieren? \n\n Eine Übersicht über andere Programme und weitere Erklärungen finden sich hier: \n\n http://letterbox.imp.fu-berlin.de?id=%@&invitation=Mail \n\nViele Grüße!";//"Hallo!\n\nEs gibt eine neue App die es super einfach macht verschlüsselt über E-Mail zu kommunizieren. Sie heißt Letterbox und wird aktuell in einer wissenschaftlichen Studie getestet.\n\nEs wäre toll wenn du sie mal ausprobieren würdest!\n\nGehe einfach auf https://userpage.fu-berlin.de/letterbox um mitzumachen.\n\nViele Grüße!"; "noName" = "OHNE NAME"; "you" = "Deine Ablage"; "thisIsYou" = "Hier werden E-Mails, die du dir selber schickst, gesammelt"; @@ -177,23 +178,29 @@ "copied" = "Schloss wurde kopiert"; "copyKey" = "Schloss in Zwischenablage kopieren"; "NeverUpdated" = "Fehler bei Aktualisierung"; - "Invitation.Code.Title" = "Fast geschafft!"; -"Invitation.Code.Message" = "Deine Nachricht wurde versendet.\nUm sie lesen zu können, braucht man den untenstehenden Code.\nDu kannst den Code per SMS oder Messenger teilen\n\nCode: %@"; +"Invitation.Code.Message" = "Deine Nachricht wurde versendet.\nUm sie lesen zu können, braucht man den unterstehenden Code.\nDu kannst den Code per SMS oder Messenger teilen\n\nCode: %@"; "Invitation.Code.Share" = "Teilen"; "Invitation.Code.Done" = "Fertig"; "Invitation.Welcome.Title" = "Vertraulich kommunizieren"; -"Invitation.Welcome.Message" = "Du kannst pikanten oder sensiblen Texte markieren, um diese dann zu verschlüsseln. Zeige deinen Kontakten, dass man auch vertraulich kommunizieren kann."; -"Invitation.Welcome.Message.Censor" = "Du kannst pikanten oder sensiblen Texte markieren, um diese dann zu verbergen. Zeige deinen Kontakten, dass du lieber einige Informationen vertraulich mitteilen willst."; +"Invitation.Welcome.Title.InvitationMail" = "Bitte um Teilnahme"; +"Invitation.Welcome.Message" = "Du kannst pikante oder sensible Textstellen markieren, um diese dann zu verschlüsseln. Zeige deinen Kontakten, dass man auch vertraulich kommunizieren kann."; +"Invitation.Welcome.Message.Censor" = "Du kannst pikante oder sensible Textstellen markieren, um diese zu verberen. Zeige deinen Kontakten, dass du lieber einige Informationen vertraulich mitteilen willst."; +"Invitation.Welcome.Message.InvitationMail" = "Mit dieser Person kannst du noch keine Briefe austauschen. Du kannst Sie bitten mitzumachen. Nachdem die andere Person per Brief geantwortet hat, kann diese auch Briefe empfangen."; "Invitation.Welcome.Try" = "Jetzt ausprobieren"; +"Invitation.Welcome.Try.InvitationMail" = "Kontakt einladen"; "Invitation.Welcome.Later" = "Vielleicht später"; "Invitation.Welcome.Dont.Ask" = "Nicht mehr anzeigen"; "Invitation.Step.Title" = "Prima!"; "Invitation.Step.Message" = "Du wirst einen Code zum Entschlüsseln deiner Nachricht erhalten, sobald du diese versendet hast."; +"Invitation.Step.Message.Censor" = "Die markierten Textstellen werden automatisch beim Versenden unkenntlich gemacht."; "Invitation.Step.CTA" = "Weiter machen"; "Invitation.Step.Undo" = "Rückgängig machen"; "Invitation.Encrypt" = "Verschlüsseln"; "Invitation.Encrypt.Censor" = "Verbergen"; "Invitation.Decrypt" = "Entschlüsseln"; "Invitation.Decrypt.Censor" = "Offenlegen"; -"Invitation.CensorFooter" = "\nWarum ist nicht alles lesbar?\nEine unverschlüsselte E-Mail ist wie eine Postkarte, auch der E-Mail-Provider und vielleicht Andere können mitlesen. Einige Teile der Nachricht sind privat oder pikant, sollten darum verborgen bleiben und wurden darum geschwärzt.\nDein Gegenüber nutzt bereits mit Letterbox ein Programm umdie Kommunikation vor den neugierigen Augen von Anderen zu schützen. Wenn Du auch mitmachst, erreicht ihr beide gemeinsam das Ziel.\nFür mehr Informationen finden sich auf https://userpage.fu-berlin.de/wieseoli/letterbox "; +"Invitation.CensorFooter" = "\n\n____________________________\n\nWarum ist nicht alles lesbar?\n\nEine unverschlüsselte E-Mail ist wie eine Postkarte; der E-Mail-Provider und möglicherweise auch Andere können mitlesen. Einige Teile dieser Nachricht sind privat oder pikant. Sie sollen vor Mitlesern verborgen bleiben und wurden darum geschwärzt.\n\nDein Gegenüber nutzt mit Letterbox bereits ein Programm um die Kommunikation vor den neugierigen Augen Anderer zu schützen. Wenn Du auch mitmachst, erreicht ihr beide gemeinsam das Ziel.\n\nMehr Informationen finden sich unter: %@\n\n"; +"Invitation.EncryptionFooter" = "\n\n____________________________\n\nTeile dieser E-Mail sind verschlüsselt!\n\nEine unverschlüsselte E-Mail ist wie eine Postkarte; der E-Mail-Provider und möglicherweise auch Andere können mitlesen. Einige Teile dieser Nachricht sind privat oder pikant. Sie sollen vor Mitlesern verborgen bleiben und wurden darum geschwärzt.\n\nDein Gegenüber nutzt mit Letterbox bereits ein Programm um die Kommunikation vor den neugierigen Augen Anderer zu schützen. Wenn Du auch mitmachst, erreicht ihr beide gemeinsam das Ziel.\n\nDu kannst die verschlüsselten Wörter jederzeit unter %@ entschlüsseln.\n\n"; +"Invitation.ComposeMail" = "Die E-Mail kannst du nach deinen Wünschen anpassen. Zur wissenschaftlichen Untersuchung wird der Inhalt dieser E-Mail auch gespeichert."; +"Mail.Signature" = "\n\n____________________________\n\nVerfasst mit Letterbox. Mehr Informationen: http://letterbox.imp.fu-berlin.de?invitation=0\n\n"; diff --git a/enzevalos_iphone/en.lproj/Localizable.strings b/enzevalos_iphone/en.lproj/Localizable.strings index c2cce69776a1ef902fcd55b9fb6759a61971955a..962ff881c3cc34b2051e19b557250461f5f853ad 100644 --- a/enzevalos_iphone/en.lproj/Localizable.strings +++ b/enzevalos_iphone/en.lproj/Localizable.strings @@ -79,13 +79,13 @@ "Plaintext" = "Klartext"; "Postcard" = "Postkarte"; "PostcardDescription" = "• Eine Postkarte ist eine E-Mail, wie du sie bisher kennst\n• Weder vertraulich, noch steht fest, ob sie gefälscht wurde\n• Von jedem lesbar und veränderbar"; -"Re" = "AW"; +"Re" = "Re"; "ReadFollowingPages" = "Wir wollen sichere E-Mail einfach nutzbar machen.\nDafür lies dir bitte die kommenden drei Seiten durch."; "ReadMailOnOtherDevice" = "Auf anderem Gerät lesen"; "ReadOnOtherDevices" = "Briefe auf anderen Geräten lesen!"; "Receive" = "Empfangen"; "ReceiveError" = "Ein Fehler ist aufgetreten"; //mehr spezifizieren? -"ReceiveDamagedInfo" = "Mit dieser Nachricht stimmt was nicht. Der Inhalt könnte kompromitiert oder manipuliert sein."; +"ReceiveDamagedInfo" = "Mit dieser Nachricht stimmt was nicht. Der Inhalt könnte kompromittiert oder manipuliert sein."; "ReceiveSecureInfo" = "Diese Nachricht war ordnungsgemäß verschlossen. Sie kann nicht von Dritten gelesen werden. Die Identität des Absenders wurde bestätigt"; "ReceiveInsecureInfo" = "Diese Nachricht wurde unverschlüsselt gesendet und konnte somit von Allen auf dem Weg mitgelesen werden. Die Identität des Absenders konnte nicht bestätigt werden und der Inhalt könnte manipuliert sein."; "ReceiveInsecureInfoVerified" = "Diese Nachricht wurde unverschlüsselt gesendet und konnte somit von Allen auf dem Weg mitgelesen werden. Die Identität des Absenders wurde bestätigt und die Nachricht wurde nicht verändert."; @@ -97,7 +97,8 @@ "Secure" = "Sicher"; "Send" = "Senden"; "SendError" = "Ein Fehler ist aufgetreten"; //mehr spezifizieren? -"SendInsecureInfo" = "Diese Nachricht würde unsicher an alle orange eingefärbten Kontakte gesendet werden. Somit kann sie unterwegs von anderen gelesen oder manipuliert werden. Du könntest die orangen Kontakte einladen Enzavalos zu verwenden, um sicher mit ihnen zu kommunizieren."; //anstatt unterwegs: auf ihrem Weg +"SendInsecureInfo" = "Diese Nachricht würde unsicher an alle orange eingefärbten Kontakte gesendet werden. Somit kann sie unterwegs von anderen gelesen oder manipuliert werden. Du könntest die orangen Kontakte einladen Letterbox zu verwenden, um sicher mit ihnen zu kommunizieren."; //anstatt unterwegs: auf ihrem Weg +"SendInsecureInfoAll" = "Diese Nachricht würde unsicher an alle Kontakte gesendet werden. Somit kann sie unterwegs von anderen gelesen oder manipuliert werden. Du könntest die orangen Kontakte einladen Letterbox zu verwenden, um sicher mit ihnen zu kommunizieren."; //anstatt unterwegs: auf ihrem Weg "SendSecureInfo" = "Super! Diese Nachricht würde sicher versendet werden. Somit ist ihr Inhalt vor neugierigen Augen geschützt und kann nicht manipuliert werden."; "SendSuccess" = "Erfolgreich gesendet"; "Sent" = "Gesendet"; @@ -148,15 +149,18 @@ "newKeyHeadline" = "Neues Schloss"; "newKeyText" = "Diese Nachricht wurde mit einem neuem Schloss verbunden. Dies kann passieren wenn der Gesprächspartner ein neues Gerät hat oder wenn ein Dritter diese Nachricht gefälscht hat."; "inviteContacts" = "Unsichere Kontakte einladen"; +"inviteContacts.Censor" = "Unsichere Kontakte einladen"; "inviteSubject" = "Lass uns unsere E-Mails verschlüsseln!"; -"inviteText" = "Hallo!\n\nEs gibt eine neue App die es super einfach macht verschlüsselt über E-Mail zu kommunizieren. Sie heißt Letterbox und wird aktuell in einer wissenschaftlichen Studie getestet.\n\nEs wäre toll wenn du sie mal ausprobieren würdest!\n\nGehe einfach auf https://userpage.fu-berlin.de/wieseoli/letterbox um mitzumachen.\n\nViele Grüße!"; +"inviteText" = "Hallo, \n\nbisher waren unsere E-Mails immer wie Postkarten und die E-Mail-Provider konnten immer mitlesen. Davor schützt Ende-Zu-Ende-Verschlüsselung. Ich probiere gerade Letterbox aus, aber es gibt auch andere Programme. Letterbox ist besonders einfach und unkompliziert. Wollen wir es mal gemeinsam ausprobieren? \n\n Eine Übersicht über andere Programme und weitere Erklärungen finden sich hier: \n\n http://letterbox.imp.fu-berlin.de?id=%@&invitation=Mail \n\nViele Grüße!";//"Hallo!\n\nEs gibt eine neue App die es super einfach macht verschlüsselt über E-Mail zu kommunizieren. Sie heißt Letterbox und wird aktuell in einer wissenschaftlichen Studie getestet.\n\nEs wäre toll wenn du sie mal ausprobieren würdest!\n\nGehe einfach auf https://userpage.fu-berlin.de/letterbox um mitzumachen.\n\nViele Grüße!"; "noName" = "OHNE NAME"; "you" = "Deine Ablage"; "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" = "Als Brief senden"; +"sendSecureIfPossible" = "Wenn möglich als Brief senden"; "sendInsecure" = "Als Postkarte verfassen"; +"sendInsecureAll" = "An alle als Postkarte verfassen"; +"sendSecure" = "Als Brief senden"; "verifyContact" = "Kontakt verifizieren"; "scanQRCode" = "Scanne den QR Code des Kontaktes"; "wrongQRCode" = "Kein passender QR Code gefunden"; @@ -174,22 +178,29 @@ "copied" = "Schloss wurde kopiert"; "copyKey" = "Schloss in Zwischenablage kopieren"; "NeverUpdated" = "Fehler bei Aktualisierung"; - "Invitation.Code.Title" = "Fast geschafft!"; -"Invitation.Code.Message" = "Deine Nachricht wurde versendet.\nUm sie lesen zu können, braucht man den untenstehenden Code.\nDu kannst den Code per SMS oder Messenger teilen\n\nCode: %@"; +"Invitation.Code.Message" = "Deine Nachricht wurde versendet.\nUm sie lesen zu können, braucht man den unterstehenden Code.\nDu kannst den Code per SMS oder Messenger teilen\n\nCode: %@"; "Invitation.Code.Share" = "Teilen"; "Invitation.Code.Done" = "Fertig"; -"Invitation.Welcome.Title" = "Sicher kommunizieren"; -"Invitation.Welcome.Message" = "Du kannst pikanten oder sensiblen Texte markieren, um diese dann zu verschlüsseln. Zeige deinen Kontakten, dass man auch sicher kommunizieren kann."; +"Invitation.Welcome.Title" = "Vertraulich kommunizieren"; +"Invitation.Welcome.Title.InvitationMail" = "Bitte um Teilnahme"; +"Invitation.Welcome.Message" = "Du kannst pikante oder sensible Textstellen markieren, um diese dann zu verschlüsseln. Zeige deinen Kontakten, dass man auch vertraulich kommunizieren kann."; +"Invitation.Welcome.Message.Censor" = "Du kannst pikante oder sensible Textstellen markieren, um diese zu verberen. Zeige deinen Kontakten, dass du lieber einige Informationen vertraulich mitteilen willst."; +"Invitation.Welcome.Message.InvitationMail" = "Mit dieser Person kannst du noch keine Briefe austauschen. Du kannst Sie bitten mitzumachen. Nachdem die andere Person per Brief geantwortet hat, kann diese auch Briefe empfangen."; "Invitation.Welcome.Try" = "Jetzt ausprobieren"; +"Invitation.Welcome.Try.InvitationMail" = "Kontakt einladen"; "Invitation.Welcome.Later" = "Vielleicht später"; "Invitation.Welcome.Dont.Ask" = "Nicht mehr anzeigen"; "Invitation.Step.Title" = "Prima!"; -"Invitation.Step.Message" = "Du wirst einen Code zum entschlüsseln deiner Nachricht erhalten, sobald du diese versendet hast."; +"Invitation.Step.Message" = "Du wirst einen Code zum Entschlüsseln deiner Nachricht erhalten, sobald du diese versendet hast."; +"Invitation.Step.Message.Censor" = "Die markierten Textstellen werden automatisch beim Versenden unkenntlich gemacht."; "Invitation.Step.CTA" = "Weiter machen"; "Invitation.Step.Undo" = "Rückgängig machen"; "Invitation.Encrypt" = "Verschlüsseln"; "Invitation.Encrypt.Censor" = "Verbergen"; "Invitation.Decrypt" = "Entschlüsseln"; "Invitation.Decrypt.Censor" = "Offenlegen"; - +"Invitation.CensorFooter" = "\n\n____________________________\n\nWarum ist nicht alles lesbar?\n\nEine unverschlüsselte E-Mail ist wie eine Postkarte; der E-Mail-Provider und möglicherweise auch Andere können mitlesen. Einige Teile dieser Nachricht sind privat oder pikant. Sie sollen vor Mitlesern verborgen bleiben und wurden darum geschwärzt.\n\nDein Gegenüber nutzt mit Letterbox bereits ein Programm um die Kommunikation vor den neugierigen Augen Anderer zu schützen. Wenn Du auch mitmachst, erreicht ihr beide gemeinsam das Ziel.\n\nMehr Informationen finden sich unter: %@\n\n"; +"Invitation.EncryptionFooter" = "\n\n____________________________\n\nTeile dieser E-Mail sind verschlüsselt!\n\nEine unverschlüsselte E-Mail ist wie eine Postkarte; der E-Mail-Provider und möglicherweise auch Andere können mitlesen. Einige Teile dieser Nachricht sind privat oder pikant. Sie sollen vor Mitlesern verborgen bleiben und wurden darum geschwärzt.\n\nDein Gegenüber nutzt mit Letterbox bereits ein Programm um die Kommunikation vor den neugierigen Augen Anderer zu schützen. Wenn Du auch mitmachst, erreicht ihr beide gemeinsam das Ziel.\n\nDu kannst die verschlüsselten Wörter jederzeit unter %@ entschlüsseln.\n\n"; +"Invitation.ComposeMail" = "Die E-Mail kannst du nach deinen Wünschen anpassen. Zur wissenschaftlichen Untersuchung wird der Inhalt dieser E-Mail auch gespeichert."; +"Mail.Signature" = "\n\n____________________________\n\nVerfasst mit Letterbox. Mehr Informationen: http://letterbox.imp.fu-berlin.de?invitation=0\n\n"; diff --git a/enzevalos_iphone/old.swift b/enzevalos_iphone/old.swift deleted file mode 100644 index 0ddc4d13cdb3016efff6358b0a82d34c32558427..0000000000000000000000000000000000000000 --- a/enzevalos_iphone/old.swift +++ /dev/null @@ -1,218 +0,0 @@ -// -// KeyRecord.swift -// enzevalos_iphone -// -// Created by Oliver Wiese on 06/01/17. -// Copyright © 2017 fu-berlin. All rights reserved. -// - -import Foundation -import Contacts -import UIKit -/* -open class KeyRecord: Record { - - /* - A record contains a signing key (or none because of insecure communication), a contact (inlucding mail-addresses) and mails. - For each key we have a different record for mailboxes. Mails and contact are affliate with the key. - Each mail is signed with the key or unsigned. The contact contains the ''from-'' mail-addresses of signed mails (or unsigned). - */ - - let keyID: String? - let cryptoscheme = CryptoScheme.PGP - let folder: Folder? - open var isSecure: Bool = false - open var ezContact: EnzevalosContact - - var pgpKey: Key?{ - get{ - if let k = keyID{ - let pgp = SwiftPGP() - return pgp.loadKey(id: k) - } - return nil - } - } - - var storedKey: PersistentKey?{ - get{ - if let k = keyID{ - return DataHandler.handler.findKey(keyID: k) - } - return nil - } - - } - - public var isVerified: Bool{ - get{ - if let k = keyID{ - if let pk = DataHandler.handler.findKey(keyID: k){ - return pk.isVerified() - } - } - return false - - } - } - - var fingerprint: String?{ - get{ - if let k = pgpKey{ - if let pk = k.publicKey{ - return pk.fingerprint.description() - } - else if let sk = k.secretKey{ - return sk.fingerprint.description() - } - return k.keyID.longIdentifier - } - return nil - } - } - - - open var mails: [PersistentMail] { - get{ - return mailsInFolder(folder: folder) - } - } - - open var addresses: [MailAddress] { - return Array(ezContact.addresses) as! [MailAddress] - } - - var addressNames:[String]{ - get{ - let adrs = addresses - var names = [String]() - for adr in adrs{ - names.append(adr.mailAddress) - } - return names - } - } - - open var name: String { - return ezContact.name - } - open var hasKey: Bool { - // Public encryption key. May missing for secure mails since mail is only signed and encrypted - return keyID != nil - } - - - open var cnContact: CNContact? { - return ezContact.cnContact - } - - open var image: UIImage { - return ezContact.getImageOrDefault() - } - open var color: UIColor { - return ezContact.getColor() - } - - - public init(keyID: String?, contact: EnzevalosContact, folder: Folder?) { - self.keyID = keyID - ezContact = contact - self.folder = folder - if keyID != nil{ - isSecure = true - } - } - - public init(contact: EnzevalosContact, folder: Folder?){ - keyID = nil - ezContact = contact - self.folder = folder - isSecure = false - } - - public init (keyID: String, folder: Folder?){ - self.keyID = keyID - self.folder = folder - isSecure = true - if let contact = DataHandler.handler.getContact(keyID: keyID){ - self.ezContact = contact - } - else{ - //TODO create Contact? - ezContact = DataHandler.handler.getContact(name: "ERROR", address: "ERROR No adr to key", key: keyID, prefer_enc: false) - } - } - - func verify(){ - if let k = keyID{ - if let pk = DataHandler.handler.findKey(keyID: k){ - pk.verify() - } - } - } - - func mailsInFolder(folder: Folder?) -> [PersistentMail]{ - let folderMails = DataHandler.handler.allMailsInFolder(key: keyID, contact: ezContact, folder: folder, isSecure: isSecure) - return folderMails - } - open func showInfos() { - print("----------------- \n \n") - print("Name: \(String(describing: ezContact.displayname)) | State: \(hasKey) | #Mails: \(mails.count)") - print("First mail: \(String(describing: mails.first?.uid)) | Adr: \(String(describing: mails.first?.from.mailAddress)) | date: \(String(describing: mails.first?.date.description)) ") - print("subj: \(String(describing: mails.first?.subject?.capitalized))") - print("----------- \n \n") - } - - open func getImageOrDefault() -> UIImage { - return ezContact.getImageOrDefault() - } - - func matchMail(mail: PersistentMail) -> Bool{ - if self.isSecure == mail.isSecure && (self.folder == mail.folder || self.folder == nil){ - if isSecure && self.keyID == mail.keyID { - return true - } - else if !isSecure { - if self.ezContact == mail.from.contact && mail.from.contact != nil{ - return true - } - for adr in addresses{ - if adr.mailAddress == mail.from.mailAddress { - return true - } - - } - } - } - return false - } - -} - - - -private func isEmpty(_ contact: KeyRecord) -> Bool { - return contact.mails.count == 0 -} - - -public func == (lhs: KeyRecord, rhs: KeyRecord) -> Bool { - if isEmpty(lhs) { - return lhs.hasKey == rhs.hasKey && lhs.keyID == rhs.keyID - } - if isEmpty(rhs) { - return lhs.hasKey == rhs.hasKey && lhs.keyID == rhs.keyID - } - return lhs.mails.first!.date == rhs.mails.first!.date && lhs.hasKey == rhs.hasKey && lhs.keyID == rhs.keyID -} - -public func < (lhs: KeyRecord, rhs: KeyRecord) -> Bool { - if isEmpty(lhs) { - return true - } - if isEmpty(rhs) { - return false - } - return lhs.mails.first!.date > rhs.mails.first!.date -} - */