diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index 05654d1b07..a58287502e 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -92,6 +92,9 @@ AFCE353527E4ED5900FEA6C2 /* DateFormatter+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */; }; AFCE353727E4ED7B00FEA6C2 /* NCShareCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */; }; AFCE353927E5DE0500FEA6C2 /* Shareable.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* Shareable.swift */; }; + AFCE353927E5DE0500FEA6C2 /* NCShare+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */; }; + B568C2C92DA7CE560072FCB4 /* E2EETests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B568C2C82DA7CE560072FCB4 /* E2EETests.swift */; }; + C04E2F232A17BB4D001BAD85 /* FilesIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04E2F222A17BB4D001BAD85 /* FilesIntegrationTests.swift */; }; D575039F27146F93008DC9DC /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extension.swift */; }; D5B6AA7827200C7200D49C24 /* NCActivityTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */; }; F310B1EF2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = F310B1EE2BA862F1001C42F5 /* NCViewerMedia+VisionKit.swift */; }; @@ -1330,6 +1333,8 @@ AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extension.swift"; sourceTree = ""; }; AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareCells.swift; sourceTree = ""; }; AFCE353827E5DE0400FEA6C2 /* Shareable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shareable.swift; sourceTree = ""; }; + AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCShare+Helper.swift"; sourceTree = ""; }; + B568C2C82DA7CE560072FCB4 /* E2EETests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = E2EETests.swift; sourceTree = ""; }; C0046CDA2A17B98400D87C9D /* NextcloudUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C04E2F202A17BB4D001BAD85 /* NextcloudIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCActivityTableViewCell.swift; sourceTree = ""; }; @@ -2118,6 +2123,8 @@ isa = PBXGroup; children = ( AA52EB452D42AC5A0089C348 /* Placeholder.swift */, + B568C2C82DA7CE560072FCB4 /* E2EETests.swift */, + AF8ED1FB2757821000B8DBC4 /* NextcloudUnitTests.swift */, ); path = NextcloudUnitTests; sourceTree = ""; diff --git a/Tests/NextcloudUnitTests/E2EETests.swift b/Tests/NextcloudUnitTests/E2EETests.swift new file mode 100644 index 0000000000..bee1c1aa3f --- /dev/null +++ b/Tests/NextcloudUnitTests/E2EETests.swift @@ -0,0 +1,90 @@ +// +// E2EETests.swift +// NextcloudTests +// +// Created by A200020526 on 26/05/23. +// Copyright © 2023 Marino Faggiana. All rights reserved. +// + +@testable import Nextcloud +import XCTest +import TOPasscodeViewController + +final class E2EETests: XCTestCase { + + var manageE2EE: NCManageE2EE! + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + manageE2EE = NCManageE2EE() + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + manageE2EE = nil + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + + // MARK: - Initialization + + func testInitialization() { + XCTAssertTrue(manageE2EE.endToEndInitialize.delegate === manageE2EE) + XCTAssertFalse(manageE2EE.isEndToEndEnabled) + XCTAssertEqual(manageE2EE.statusOfService, NSLocalizedString("_status_in_progress_", comment: "")) + } + + // MARK: - Delegate + + func testEndToEndInitializeSuccess() { + manageE2EE.endToEndInitializeSuccess() + XCTAssertTrue(manageE2EE.isEndToEndEnabled) + } + + // MARK: - Passcode + + func testRequestPasscodeType() { + // TODO: Implement this test case + } + + func testCorrectPasscode_startE2E() { + manageE2EE.passcodeType = "startE2E" + manageE2EE.correctPasscode() + // TODO: Add assertions for the expected behavior after entering the correct passcode for starting E2E + } + + func testCorrectPasscode_readPassphrase() { + manageE2EE.passcodeType = "readPassphrase" + // TODO: Simulate entering the correct passcode and verify the expected behavior + } + + func testCorrectPasscode_removeLocallyEncryption() { + manageE2EE.passcodeType = "removeLocallyEncryption" + // TODO: Simulate entering the correct passcode and verify the expected behavior + } + + func testDidPerformBiometricValidationRequest() { + let passcodeViewController = TOPasscodeViewController(passcodeType: .sixDigits, allowCancel: true) + manageE2EE.didPerformBiometricValidationRequest(in: passcodeViewController) + // TODO: Add assertions for the expected behavior after performing biometric validation + } + + func testDidTapCancel() { + let passcodeViewController = TOPasscodeViewController(passcodeType: .sixDigits, allowCancel: true) + manageE2EE.didTapCancel(in: passcodeViewController) + // TODO: Add assertions for the expected behavior after tapping cancel + } +} diff --git a/iOSClient/Settings/E2EE/NCEndToEndInitialize.swift b/iOSClient/Settings/E2EE/NCEndToEndInitialize.swift index 19b0457088..2df29b87cb 100644 --- a/iOSClient/Settings/E2EE/NCEndToEndInitialize.swift +++ b/iOSClient/Settings/E2EE/NCEndToEndInitialize.swift @@ -128,8 +128,8 @@ class NCEndToEndInitialize: NSObject { let privateKey = String(data: keyData, encoding: .utf8) { NCKeychain().setEndToEndPrivateKey(account: account, privateKey: privateKey) } else { - let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "Serious internal error to decrypt Private Key") - NCContentPresenter().messageNotification("E2E decrypt privateKey", error: error, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, priority: .max) + let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: NSLocalizedString("_e2e_error_incorrect_passphrase_", comment: "")) + NCContentPresenter().messageNotification(NSLocalizedString("_e2e_error_passphrase_title", comment: ""), error: error, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, priority: .max) return } @@ -159,7 +159,7 @@ class NCEndToEndInitialize: NSObject { } }) - let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ -> Void in + let cancel = UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .cancel) { _ -> Void in } alertController.addAction(ok) diff --git a/iOSClient/Settings/E2EE/NCManageE2EEView.swift b/iOSClient/Settings/E2EE/NCManageE2EEView.swift index 9f26d5a7da..4f33d8fe1a 100644 --- a/iOSClient/Settings/E2EE/NCManageE2EEView.swift +++ b/iOSClient/Settings/E2EE/NCManageE2EEView.swift @@ -24,6 +24,18 @@ import SwiftUI import NextcloudKit +@objc class NCManageE2EEInterface: NSObject { + + @objc func makeShipDetailsUI(account: String) -> UIViewController { + + let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController + let details = NCManageE2EEView(model: NCManageE2EE(controller: controller)) + let vc = UIHostingController(rootView: details) + vc.title = NSLocalizedString("_e2e_settings_", comment: "") + return vc + } +} + struct NCManageE2EEView: View { @ObservedObject var model: NCManageE2EE @Environment(\.presentationMode) var presentationMode @@ -32,104 +44,95 @@ struct NCManageE2EEView: View { VStack { if model.isEndToEndEnabled { List { - Section(header: Text(""), footer: Text(model.statusOfService + "\n\n" + "End-to-End Encryption " + model.capabilities.capabilityE2EEApiVersion)) { + Section(header: Text(""), footer: Text("End-to-End Encryption " + NCGlobal.shared.capabilityE2EEApiVersion)) { Label { Text(NSLocalizedString("_e2e_settings_activated_", comment: "")) } icon: { Image(systemName: "checkmark.circle.fill") .resizable() .scaledToFit() - .font(Font.system(.body).weight(.light)) - .frame(width: 25, height: 25) .foregroundColor(.green) } } - HStack { + + Section(header: Text(""), footer: Text(NSLocalizedString("_read_passphrase_description_", comment: ""))) { Label { Text(NSLocalizedString("_e2e_settings_read_passphrase_", comment: "")) } icon: { Image(systemName: "eye") .resizable() .scaledToFit() - .font(Font.system(.body).weight(.light)) - .frame(width: 25, height: 25) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) + .foregroundColor(Color(NCBrandColor.shared.iconColor)) + .frame(width: 20, height: 30) } - Spacer() - } - .contentShape(Rectangle()) - .onTapGesture { - if NCKeychain().passcode != nil { - model.requestPasscodeType("readPassphrase") - } else { - NCContentPresenter().showInfo(error: NKError(errorCode: 0, errorDescription: "_e2e_settings_lock_not_active_")) + .onTapGesture { + if NCKeychain().passcode != nil { + model.requestPasscodeType("readPassphrase") + } else { + NCContentPresenter().showInfo(error: NKError(errorCode: 0, errorDescription: "_e2e_settings_lock_not_active_")) + } } } - HStack { + + let removeStrDesc1 = NSLocalizedString("_remove_passphrase_desc_1_", comment: "") + let removeStrDesc2 = NSLocalizedString("_remove_passphrase_desc_2_", comment: "") + let removeStrDesc = String(format: "%@\n\n%@", removeStrDesc1, removeStrDesc2) + Section(header: Text(""), footer: Text(removeStrDesc)) { Label { Text(NSLocalizedString("_e2e_settings_remove_", comment: "")) } icon: { - Image(systemName: "xmark") + Image(systemName: "trash") .resizable() .scaledToFit() - .font(Font.system(.body).weight(.light)) - .frame(width: 25, height: 15) - .foregroundColor(Color(NCBrandColor.shared.iconImageColor)) + .foregroundColor(Color(NCBrandColor.shared.iconColor)) + .frame(width: 20, height: 30) } - Spacer() - } - .contentShape(Rectangle()) - .onTapGesture { - if NCKeychain().passcode != nil { - model.requestPasscodeType("removeLocallyEncryption") - } else { - NCContentPresenter().showInfo(error: NKError(errorCode: 0, errorDescription: "_e2e_settings_lock_not_active_")) + .onTapGesture { + if NCKeychain().passcode != nil { + model.requestPasscodeType("removeLocallyEncryption") + } else { + NCContentPresenter().showInfo(error: NKError(errorCode: 0, errorDescription: "_e2e_settings_lock_not_active_")) + } } } #if DEBUG deleteCerificateSection #endif } + } else { + List { - Section(header: Text(""), footer: Text(model.statusOfService + "\n\n" + "End-to-End Encryption " + model.capabilities.capabilityE2EEApiVersion)) { + let startE2EDesc1 = NSLocalizedString("_start_e2e_encryption_1_", comment: ""); + let startE2EDesc2 = NSLocalizedString("_start_e2e_encryption_2_", comment: ""); + let startE2EDesc3 = NSLocalizedString("_start_e2e_encryption_3_", comment: ""); + let startE2EDesc = String(format: "%@\n\n%@\n\n%@",startE2EDesc1,startE2EDesc2,startE2EDesc3) + Section(header: Text(""), footer: Text(startE2EDesc)) { HStack { Label { Text(NSLocalizedString("_e2e_settings_start_", comment: "")) } icon: { - Image(systemName: "play.circle") - .resizable() - .scaledToFit() - .font(Font.system(.body).weight(.light)) - .frame(width: 25, height: 25) - .foregroundColor(.green) } Spacer() } .contentShape(Rectangle()) .onTapGesture { - if NCKeychain().passcode != nil { + if let passcode = NCKeychain().passcode { model.requestPasscodeType("startE2E") } else { NCContentPresenter().showInfo(error: NKError(errorCode: 0, errorDescription: "_e2e_settings_lock_not_active_")) } } } + #if DEBUG deleteCerificateSection #endif } + .listStyle(GroupedListStyle()) } } - .navigationBarTitle(NSLocalizedString("_e2e_settings_", comment: "")) - .navigationBarTitleDisplayMode(.inline) .background(Color(UIColor.systemGroupedBackground)) - .defaultViewModifier(model) - .onChange(of: model.navigateBack) { newValue in - if newValue { - presentationMode.wrappedValue.dismiss() - } - } } @ViewBuilder @@ -144,7 +147,7 @@ struct NCManageE2EEView: View { .scaledToFit() .font(Font.system(.body).weight(.light)) .frame(width: 25, height: 25) - .foregroundColor(Color(NCBrandColor.shared.textColor2)) + .foregroundColor(Color(UIColor.systemGray)) } Spacer() } @@ -167,7 +170,7 @@ struct NCManageE2EEView: View { .scaledToFit() .font(Font.system(.body).weight(.light)) .frame(width: 25, height: 25) - .foregroundColor(Color(NCBrandColor.shared.textColor2)) + .foregroundColor(Color(UIColor.systemGray)) } Spacer() } @@ -186,5 +189,64 @@ struct NCManageE2EEView: View { } #Preview { - NCManageE2EEView(model: NCManageE2EE(controller: nil)) + let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController + NCManageE2EEView(model: NCManageE2EE(controller: controller)) +} + +// MARK: - Preview / Test + +struct SectionView: View { + + @State var height: CGFloat = 0 + @State var text: String = "" + + var body: some View { + HStack { + Text(text) + } + .frame(maxWidth: .infinity, minHeight: height, alignment: .bottomLeading) + } +} + +struct NCManageE2EEViewTest: View { + + var body: some View { + + VStack { + List { + Section(header: SectionView(height: 50, text: "Section Header View")) { + Label { + Text(NSLocalizedString("_e2e_settings_activated_", comment: "")) + } icon: { + Image(systemName: "checkmark.circle.fill") + .resizable() + .scaledToFit() + .frame(width: 25, height: 25) + .foregroundColor(.green) + } + } + Section(header: SectionView(text: "Section Header View 42")) { + Label { + Text(NSLocalizedString("_e2e_settings_activated_", comment: "")) + } icon: { + Image(systemName: "checkmark.circle.fill") + .resizable() + .scaledToFit() + .frame(width: 25, height: 25) + .foregroundColor(.red) + } + } + } + } + } +} + +struct NCManageE2EEView_Previews: PreviewProvider { + static var previews: some View { + + // swiftlint:disable force_cast + let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController + NCManageE2EEView(model: NCManageE2EE(controller: controller)) + // swiftlint:enable force_cast + } } diff --git a/iOSClient/Settings/NCManageE2EE.swift b/iOSClient/Settings/NCManageE2EE.swift new file mode 100644 index 0000000000..6cab2b6839 --- /dev/null +++ b/iOSClient/Settings/NCManageE2EE.swift @@ -0,0 +1,374 @@ +// +// NCManageE2EE.swift +// Nextcloud +// +// Created by Marino Faggiana on 17/11/22. +// Copyright © 2022 Marino Faggiana. All rights reserved. +// +// Author Marino Faggiana +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +import SwiftUI +import NextcloudKit +import TOPasscodeViewController +import LocalAuthentication + +@objc class NCManageE2EEInterface: NSObject { + + @objc func makeShipDetailsUI(account: String) -> UIViewController { + + let details = NCViewE2EE(account: account) + let vc = UIHostingController(rootView: details) + vc.title = NSLocalizedString("_e2e_settings_", comment: "") + return vc + } +} + +class NCManageE2EE: NSObject, ObservableObject, NCEndToEndInitializeDelegate, TOPasscodeViewControllerDelegate { + + let endToEndInitialize = NCEndToEndInitialize() + let appDelegate = (UIApplication.shared.delegate as? AppDelegate)! + var passcodeType = "" + + @Published var isEndToEndEnabled: Bool = false + @Published var statusOfService: String = NSLocalizedString("_status_in_progress_", comment: "") + + override init() { + super.init() + + endToEndInitialize.delegate = self + isEndToEndEnabled = NCKeychain().isEndToEndEnabled(account: appDelegate.account) + if isEndToEndEnabled { + statusOfService = NSLocalizedString("_status_e2ee_configured_", comment: "") + } else { + endToEndInitialize.statusOfService { error in + if error == .success { + self.statusOfService = NSLocalizedString("_status_e2ee_on_server_", comment: "") + } else { + self.statusOfService = NSLocalizedString("_status_e2ee_not_setup_", comment: "") + } + } + } + } + + // MARK: - Delegate + + func endToEndInitializeSuccess() { + isEndToEndEnabled = true + } + + // MARK: - Passcode + + @objc func requestPasscodeType(_ passcodeType: String) { + + let laContext = LAContext() + var error: NSError? + + let passcodeViewController = TOPasscodeViewController(passcodeType: .sixDigits, allowCancel: true) + passcodeViewController.delegate = self + passcodeViewController.keypadButtonShowLettering = false + if NCKeychain().touchFaceID, laContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) { + if error == nil { + if laContext.biometryType == .faceID { + passcodeViewController.biometryType = .faceID + passcodeViewController.allowBiometricValidation = true + } else if laContext.biometryType == .touchID { + passcodeViewController.biometryType = .touchID + } + passcodeViewController.allowBiometricValidation = true + passcodeViewController.automaticallyPromptForBiometricValidation = true + } + } + + self.passcodeType = passcodeType + appDelegate.window?.rootViewController?.present(passcodeViewController, animated: true) + } + + @objc func correctPasscode() { + + switch self.passcodeType { + case "startE2E": + endToEndInitialize.initEndToEndEncryption() + case "readPassphrase": + if let e2ePassphrase = NCKeychain().getEndToEndPassphrase(account: appDelegate.account) { + print("[INFO]Passphrase: " + e2ePassphrase) + let message = "\n" + NSLocalizedString("_e2e_settings_the_passphrase_is_", comment: "") + "\n\n\n" + e2ePassphrase + let alertController = UIAlertController(title: NSLocalizedString("_info_", comment: ""), message: message, preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in })) + alertController.addAction(UIAlertAction(title: NSLocalizedString("_copy_passphrase_", comment: ""), style: .default, handler: { _ in + UIPasteboard.general.string = e2ePassphrase + })) + appDelegate.window?.rootViewController?.present(alertController, animated: true) + } + case "removeLocallyEncryption": + let alertController = UIAlertController(title: NSLocalizedString("_e2e_settings_remove_", comment: ""), message: NSLocalizedString("_e2e_settings_remove_message_", comment: ""), preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: NSLocalizedString("_remove_", comment: ""), style: .default, handler: { _ in + NCKeychain().clearAllKeysEndToEnd(account: self.appDelegate.account) + self.isEndToEndEnabled = NCKeychain().isEndToEndEnabled(account: self.appDelegate.account) + })) + alertController.addAction(UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .default, handler: { _ in })) + appDelegate.window?.rootViewController?.present(alertController, animated: true) + default: + break + } + } + + func passcodeViewController(_ passcodeViewController: TOPasscodeViewController, isCorrectCode code: String) -> Bool { + + if code == NCKeychain().passcode { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + self.correctPasscode() + } + return true + } else { + return false + } + } + + func didPerformBiometricValidationRequest(in passcodeViewController: TOPasscodeViewController) { + + LAContext().evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: NCBrandOptions.shared.brand) { success, _ in + if success { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + passcodeViewController.dismiss(animated: true) + self.correctPasscode() + } + } + } + } + + func didTapCancel(in passcodeViewController: TOPasscodeViewController) { + passcodeViewController.dismiss(animated: true) + } +} + +// MARK: Views + +struct NCViewE2EE: View { + + @ObservedObject var manageE2EE = NCManageE2EE() + @State var account: String = "" + + var body: some View { + + VStack { + + if manageE2EE.isEndToEndEnabled { + + List { + + Section(header: Text(""), footer: Text("End-to-End Encryption " + NCGlobal.shared.capabilityE2EEApiVersion)) { + Label { + Text(NSLocalizedString("_e2e_settings_activated_", comment: "")) + } icon: { + Image(systemName: "checkmark.circle.fill") + .resizable() + .scaledToFit() + .foregroundColor(.green) + } + } + + Section(header: Text(""), footer: Text(NSLocalizedString("_read_passphrase_description_", comment: ""))) { + Label { + Text(NSLocalizedString("_e2e_settings_read_passphrase_", comment: "")) + } icon: { + Image(systemName: "eye") + .resizable() + .scaledToFit() + .foregroundColor(Color(NCBrandColor.shared.iconColor)) + .frame(width: 20, height: 30) + } + .onTapGesture { + if NCKeychain().passcode != nil { + manageE2EE.requestPasscodeType("readPassphrase") + } else { + NCContentPresenter().showInfo(error: NKError(errorCode: 0, errorDescription: "_e2e_settings_lock_not_active_")) + } + } + } + + let removeStrDesc1 = NSLocalizedString("_remove_passphrase_desc_1_", comment: "") + let removeStrDesc2 = NSLocalizedString("_remove_passphrase_desc_2_", comment: "") + let removeStrDesc = String(format: "%@\n\n%@", removeStrDesc1, removeStrDesc2) + Section(header: Text(""), footer: Text(removeStrDesc)) { + Label { + Text(NSLocalizedString("_e2e_settings_remove_", comment: "")) + } icon: { + Image(systemName: "trash") + .resizable() + .scaledToFit() + .foregroundColor(Color(NCBrandColor.shared.iconColor)) + .frame(width: 20, height: 30) + } + .onTapGesture { + if NCKeychain().passcode != nil { + manageE2EE.requestPasscodeType("removeLocallyEncryption") + } else { + NCContentPresenter().showInfo(error: NKError(errorCode: 0, errorDescription: "_e2e_settings_lock_not_active_")) + } + } + } +#if DEBUG + DeleteCerificateSection() +#endif + } + + } else { + + List { + let startE2EDesc1 = NSLocalizedString("_start_e2e_encryption_1_", comment: ""); + let startE2EDesc2 = NSLocalizedString("_start_e2e_encryption_2_", comment: ""); + let startE2EDesc3 = NSLocalizedString("_start_e2e_encryption_3_", comment: ""); + let startE2EDesc = String(format: "%@\n\n%@\n\n%@",startE2EDesc1,startE2EDesc2,startE2EDesc3) + Section(header: Text(""), footer: Text(startE2EDesc)) { + HStack { + Label { + Text(NSLocalizedString("_e2e_settings_start_", comment: "")) + } icon: { + } + Spacer() + } + .contentShape(Rectangle()) + .onTapGesture { + if let passcode = NCKeychain().passcode { + manageE2EE.requestPasscodeType("startE2E") + } else { + NCContentPresenter().showInfo(error: NKError(errorCode: 0, errorDescription: "_e2e_settings_lock_not_active_")) + } + } + } + +#if DEBUG + DeleteCerificateSection() +#endif + } + .listStyle(GroupedListStyle()) + } + } + .background(Color(UIColor.systemGroupedBackground)) + } +} + +struct DeleteCerificateSection: View { + + var body: some View { + + Section(header: Text("Delete Server keys"), footer: Text("Available only in debug mode")) { + + HStack { + Label { + Text("Delete Certificate") + } icon: { + Image(systemName: "exclamationmark.triangle") + .resizable() + .scaledToFit() + .foregroundColor(Color(UIColor.systemGray)) + } + Spacer() + } + .contentShape(Rectangle()) + .onTapGesture { + NextcloudKit.shared.deleteE2EECertificate { _, error in + if error == .success { + NCContentPresenter().messageNotification("E2E delete certificate", error: error, delay: NCGlobal.shared.dismissAfterSecond, type: .success) + } else { + NCContentPresenter().messageNotification("E2E delete certificate", error: error, delay: NCGlobal.shared.dismissAfterSecond, type: .error) + } + } + } + + HStack { + Label { + Text("Delete PrivateKey") + } icon: { + Image(systemName: "exclamationmark.triangle") + .resizable() + .scaledToFit() + .foregroundColor(Color(UIColor.systemGray)) + } + Spacer() + } + .contentShape(Rectangle()) + .onTapGesture { + NextcloudKit.shared.deleteE2EEPrivateKey { _, error in + if error == .success { + NCContentPresenter().messageNotification("E2E delete privateKey", error: error, delay: NCGlobal.shared.dismissAfterSecond, type: .success) + } else { + NCContentPresenter().messageNotification("E2E delete privateKey", error: error, delay: NCGlobal.shared.dismissAfterSecond, type: .error) + } + } + } + } + } +} + +// MARK: - Preview / Test + +struct SectionView: View { + + @State var height: CGFloat = 0 + @State var text: String = "" + + var body: some View { + HStack { + Text(text) + } + .frame(maxWidth: .infinity, minHeight: height, alignment: .bottomLeading) + } +} + +struct NCViewE2EETest: View { + + var body: some View { + + VStack { + List { + Section(header: SectionView(height: 50, text: "Section Header View")) { + Label { + Text(NSLocalizedString("_e2e_settings_activated_", comment: "")) + } icon: { + Image(systemName: "checkmark.circle.fill") + .resizable() + .scaledToFit() + .frame(width: 25, height: 25) + .foregroundColor(.green) + } + } + Section(header: SectionView(text: "Section Header View 42")) { + Label { + Text(NSLocalizedString("_e2e_settings_activated_", comment: "")) + } icon: { + Image(systemName: "checkmark.circle.fill") + .resizable() + .scaledToFit() + .frame(width: 25, height: 25) + .foregroundColor(.red) + } + } + } + } + } +} + +struct NCViewE2EE_Previews: PreviewProvider { + static var previews: some View { + + // swiftlint:disable force_cast + let account = (UIApplication.shared.delegate as! AppDelegate).account + NCViewE2EE(account: account) + // swiftlint:enable force_cast + } +} diff --git a/iOSClient/Utility/NYMnemonic/languages/english.txt b/iOSClient/Utility/NYMnemonic/languages/english.txt index 942040ed50..13755ac8cf 100755 --- a/iOSClient/Utility/NYMnemonic/languages/english.txt +++ b/iOSClient/Utility/NYMnemonic/languages/english.txt @@ -1,2048 +1,2305 @@ -abandon -ability -able -about -above -absent -absorb -abstract -absurd -abuse -access -accident -account -accuse -achieve -acid -acoustic -acquire -across -act +aal +abend +abendrot +abenteuer +aberglaube +abfahrt +abfall +abtei +achse +acht +achtung +achtzig +acidum +acker +ackerbau +ackerhof action -actor -actress -actual -adapt -add -addict -address -adjust -admit -adult -advance -advice -aerobic -affair -afford -afraid -again -age -agent -agree -ahead -aim -air -airport -aisle -alarm -album -alcohol -alert -alien -all -alley -allow -almost -alone -alpha -already -also -alter -always -amateur -amazing -among -amount -amused -analyst -anchor -ancient -anger -angle -angry -animal -ankle -announce -annual -another -answer -antenna -antique -anxiety -any -apart -apology -appear -apple -approve +ada +adam +adel +adenauer +ader +aderlass +adidas +adieu +adjektiv +adolph +adonis +adria +adverb +advokat +angina +angler +ansicht +antonio +antrag +antrieb +antritt +antwort +anwalt +apache +apartheid +apartment +aperitif +apfel +apfelmus +apfelsine +apfeltorte +apfelwein +aphorismus +aphrodite +apokalypse +apoll +apollo +apologeten +apostel +apostroph +apostrophs +apotheke +apparat april -arch -arctic -area +apropos +apsis +apulien +aquarell +aragon +arbeit +archimedes +architekt +archiv +arden +areal arena -argue +arenen +argau +arge +argentinien +arglist +argonaut +argosy +argument +argus +argusaugen +argwohn +ariane +arie +aristokrat +aristoteles +arithmetik +arizona +arkade +arkadenhof +arkansas +arktisforscher arm -armed -armor +armada +armagnac +armando +armaturen +armband +armee +armenien +armenier +armfluegeln +armhaltung +armhebel +armkettchen +armlehnen +armreif +arms +armseligkeit +armsessel +armstrong +armut army -around -arrange +arnica +arno arrest -arrive -arrow -art -artefact -artist -artwork -ask -aspect -assault -asset -assist -assume -asthma -athlete +arroganz +arsch +arterie +arthur +arzt +asbest +asien +aspirant +astrologe +astrologie +astronaut +astronomie +asyl +atelier +atem +atemzug +atheist +atheisten +atheistin +athen +athene +athlet atom -attack -attend -attitude -attract -auction -audit -august -aunt -author +aubergine +auch +audienz +audienzen +audrey +auen +auerhahn auto -autumn -average -avocado -avoid -awake -aware -away -awesome -awful -awkward -axis baby -bachelor -bacon -badge -bag -balance -balcony +bach +backup +backware +backwaren +bad +badetuch +bahamas +bahn +balearen +bali +balkan ball -bamboo -banana -banner -bar -barely -bargain -barrel -base -basic -basket -battle -beach -bean -beauty -because -become -beef -before -begin -behave -behind -believe -below -belt -bench -benefit -best -betray -better -between -beyond -bicycle -bid -bike -bind -biology -bird -birth -bitter -black -blade -blame -blanket -blast -bleak -bless -blind -blood -blossom -blouse -blue -blur -blush -board -boat -body -boil -bomb -bone -bonus -book -boost -border -boring -borrow -boss -bottom -bounce -box -boy -bracket -brain -brand -brass -brave -bread -breeze -brick -bridge +band +bank +barbar +barbara +bargeld +baron +basketball +batterie +bau +bauernhof +bauherr +baum +bazar +bazille +bedarf +beere +beet +behauptung +beifall +beine +beischlaf +beitrag +belfast +belgien +bengel +benzin +berg +bert +berta +bier +bild +billionen +billy +bindegewebe +bindeglied +birmingham +birne +blaubeere +blaubeertorte +blech +blei +bleibe +blume +blut +bonsai +boa +bob +bock +bombe +boot +bordell brief -bright -bring -brisk -broccoli -broken +bronchitis bronze -broom -brother -brown -brush -bubble -buddy -budget -buffalo -build -bulb -bulk -bullet -bundle -bunker -burden -burger -burst +buchkritik +buchmacher +buckingham +budapest +buddha +bude +buch +buechse +buechsen +bueffel +buegels +buehler +buehne +bungalow +burda +bureau +burg +burgenland bus -business -busy +butler butter -buyer -buzz -cabbage -cabin -cable -cactus -cage -cake -call -calm -camera -camp -can -canal -cancel -candy -cannon -canoe -canvas -canyon -capable -capital -captain -car -carbon -card -cargo -carpet -carry -cart -case -cash -casino -castle -casual -cat -catalog -catch -category -cattle -caught -cause -caution -cave -ceiling -celery -cement -census -century -cereal -certain -chair -chalk -champion -change -chaos -chapter -charge -chase -chat -cheap -check -cheese +buxtehude +cafe +cafeteria +calabrien +calamares +calcutta +carlo +carol +carola +carton +charakter +chefkoch chef -cherry -chest -chicken -chief -child -chimney -choice -choose -chronic -chuckle -chunk -churn -cigar -cinnamon -circle -citizen -city -civil -claim -clap -clarify -claw -clay -clean -clerk -clever -click -client -cliff -climb -clinic -clip -clock -clog -close -cloth -cloud +chemie +cheyenne +chiffre +chromosom +circus +citroen clown club -clump -cluster -clutch -coach -coast -coconut -code -coffee -coil -coin -collect -color -column -combine -come -comfort -comic -common -company -concert -conduct -confirm -congress -connect -consider -control -convince -cook -cool -copper -copy -coral -core -corn -correct -cost -cotton -couch -country -couple -course -cousin -cover -coyote -crack -cradle -craft -cram -crane -crash -crater -crawl -crazy -cream -credit -creek -crew -cricket -crime -crisp -critic -crop -cross -crouch -crowd -crucial -cruel -cruise -crumble -crunch -crush -cry -crystal -cube -culture -cup -cupboard -curious -current -curtain -curve -cushion -custom -cute -cycle -dad -damage -damp -dance -danger -daring -dash -daughter -dawn -day -deal -debate -debris -decade -december -decide -decline -decorate -decrease -deer -defense -define -defy -degree -delay -deliver -demand -demise -denial -dentist -deny -depart -depend -deposit -depth -deputy -derive -describe -desert -design -desk -despair -destroy +clubmaster +cocktail +comune +dach +dachbalken +dachboden +dackel +daemon +dammbruch +dampfbad +dante +danton +datenbank +daten +daumen +daune +daunen +david +deckblatt +deckel +decoder +defizit +deich +deichbauer +dekan +dekor +dekorateur +dekret +delikt +demokrat +demut +denkfehler +denkmal +denkspiel +depot +destillat detail -detect -develop -device -devote -diagram -dial -diamond -diary -dice +detektiv +detroit +dezember +dialog diesel -diet -differ -digital -dignity +diesellok +dieter +diether +dietrich +digitaluhr +diktat +diktatur dilemma -dinner -dinosaur -direct -dirt -disagree -discover -disease -dish -dismiss -disorder -display -distance -divert -divide -divorce -dizzy -doctor -document -dog -doll -dolphin -domain -donate -donkey -donor -door -dose -double -dove -draft -dragon +diplomat +direkt +disco +dogma +doktor +doktorarbeit +dokument +dolch +donald +donaudelta +doping +dorf +dorne +dosis +drache +drachenboot +dracula +draht +drahtzaun drama -drastic -draw -dream +drecksack +dreher +drehung +drehzahl +drei +dreieck +dreiklang dress -drift -drill -drink -drip -drive -drop -drum -dry -duck -dumb -dune -during -dust -dutch -duty -dwarf -dynamic -eager -eagle -early -earn -earth -easily -east -easy +droge +drogen +drogenbaron +dubios +dublin +duell +duft +duftnote +dumm +dunkel +dunkelheit +durst +dynamik +dynamit +ebenbild echo -ecology -economy -edge -edit -educate -effort -egg -eight -either -elbow -elder -electric -elegant -element -elephant -elevator -elite -else -embark -embody -embrace -emerge +echos +ecke +eden +edens +edinburgh +edison +editieren +editor +editorial +edmund +efeu +efeus +effekt +egal +ehebruch +ehefrau +ehezwist +ehre +eiche +eichel +eid +eidechsen +eier +eierschale +eifel +eifer +eifersucht +eiffelturm +eigenheim +eigenleben +eigensinn +eile +eilgut +eiltempo +eimer +einband +einbau +einbruch +eingabe +einheit +einhorn +einklang +einladung +einlagen +einsamkeit +einsatz +einschlag +einschuss +einzelfall +eis +eisbaer +eisbecher +eisberg +eisbombe +eisdiele +eisen +eisenbahn +ekel +elektro +elektrik +elend +elfenbein +elsass +eltern +elternbeirat +email +emanuel +emanuela +emanzipation +embargo +emblem +embolie +embyro +emilia +eminenz +eminenzen emotion -employ -empower -empty -enable -enact -end -endless -endorse -enemy -energy -enforce -engage -engine -enhance -enjoy -enlist -enough -enrich -enroll -ensure -enter -entire -entry -envelope -episode -equal -equip -era -erase -erode +ende +endrunde +endung +endungen +engel +england +enkel +enkelin +entgelt +erbgut +erdoel +erhalt +erhaltes +erhaltung +erich +erika +eritrea +erkaeltung +erkenntis +ernte +eros erosion -error -erupt -escape -essay -essence -estate -eternal -ethics -evidence -evil -evoke -evolve -exact -example -excess -exchange -excite -exclude -excuse -execute -exercise -exhaust -exhibit -exile -exist -exit -exotic -expand -expect -expire -explain -expose -express -extend -extra -eye -eyebrow -fabric -face -faculty -fade -faint -faith +erst +erzeugung +eskorte +essig +etat +eule +exil +fabel +fabian +fabrik +fabrikant +faden +fahne +fahrgast +fahrer +fahrgeld +fahrrad +falke fall -false -fame -family -famous -fan -fancy -fantasy +fallbeil +falle +fallobst +fallschirm +faltboot +faltdach +fantasie +farbe farm -fashion -fat -fatal -father -fatigue -fault -favorite -feature -february -federal -fee -feed -feel -female -fence +farmer +farn +faruk +fasan +fass +fassade +fatalismus +fatalitaet +faulenzer +faulpelz +fauna +faust +favorit +fazit +fechter +feder +federung +fegefeuer +fehde +fehler +fehlmenge +feier +feierabend +feiertag +feigling +feind +feinkost +felder +felge +felix +fell +fenchel +fenster +fensterbank +ferien +fernglas +fernost +fernseher +fernsicht +fernweh +ferrari +festakt +festakte festival -fetch -fever -few -fiber -fiction -field +fett +feuer +feueralarm +feuerwerk +fiasko +fiat +fieber figure -file +fiktion film -filter -final -find -fine +filz +fimmel +finale +finanzhai +finderlohn finger -finish -fire -firm -first -fiscal -fish -fit +fink +firlefanz +firma +firmament +fisch +fischerboot +fischfang fitness -fix -flag -flame -flash -flat -flavor -flee -flight -flip -float -flock -floor -flower -fluid -flush -fly -foam -focus -fog -foil -fold -follow -food -foot -force -forest -forget -fork -fortune -forum -forward +flagge +fleiss +fleisch +fliege +fliegen +fliegenpilz +fliese +flinte +flipper +flirt +flo +flop +flora +florenz +florett +florida +floskel +flotte +flucht +fluchtauto +fluchtburg +flug +flugabwehr +flughafen +flunder +fluss +flusspferd +flutwelle +foen +folklore +folter +folterbank +folterknecht +forschung +forst +forstamt fossil -foster -found -fox -fragile -frame -frequent -fresh -friend -fringe -frog -front -frost -frown -frozen -fruit -fuel -fun -funny -furnace -fury -future -gadget -gain -galaxy -gallery -game -gap +foto +fotoapparat +foulspiel +foyer +fracht +frack +fragment +frankfurt +franzose +fratze +frei +freibier +freiheit +freitag +freizeit +freske +freude +freund +frevel +frieden +friesland +frikadelle +friseur +frist +frohnatur +frohsinn +frosch +frucht +fruehjahr +frust +fuchs +fuenf +furie +fuss +gabe +galaxie +galeere +galerie +galgen +galilei +galizien garage -garbage -garden -garlic -garment +garten +gartenzwerg gas -gasp -gate -gather -gauge -gaze -general -genius -genre -gentle -genuine -gesture -ghost -giant +gast +gasthof +gauda +gaudi +gaul +gaukler +gaumen +gauner +gazelle +geburtstag +gedanke +geduld +gefaengnis +gefecht +gehirn +geier +geist +geizhals +georg +getto +gewehr +ghetto gift -giggle -ginger -giraffe -girl -give -glad -glance -glare -glass -glide -glimpse -globe -gloom -glory -glove -glow -glue -goat -goddess -gold -good -goose +gina +gleis +glueck gorilla -gospel -gossip -govern -gown -grab -grace -grain -grant -grape -grass -gravity -great -green -grid -grief -grit -grocery -group -grow -grunt -guard -guess -guide -guilt -guitar -gun -gym -habit -hair -half -hammer -hamster -hand -happy -harbor -hard -harsh -harvest -hat -have -hawk -hazard -head -health -heart -heavy -hedgehog -height -hello -helmet -help -hen -hero -hidden -high -hill -hint -hip -hire -history -hobby -hockey -hold -hole -holiday -hollow -home -honey -hood -hope -horn -horror -horse -hospital -host +guido +gummi +gurke +gurkensalat +gurt +guru +haar +hafen +haft +haftbefehl +halbmond +halogen +hals +handball +handbremse +handgelenk +handtasche +hannelore +hantel +harlekin +harmonie +haschisch +harz +hausarrest +hausarzt +hausschwein +haut +hawaii +heck +heckteil +hehler +heike +heimat +heino +heinrich +heinz +heirat +hektik +held +helsinki +hemd +herbert +herbst +herz +heuchler +hexen +hexerei +himalaja +himalaya +himbeere +himmel +hindu +hintergrund +hintern +hippie +hippodamus +hippodrom +hirn +hitze +hobbie +hochmut +hoftor +hoheit +hollywood +holz hotel -hour -hover -hub -huge -human -humble -humor -hundred -hungry -hunt -hurdle -hurry -hurt -husband -hybrid -ice -icon -idea -identify -idle -ignore -ill -illegal -illness -image -imitate -immense -immune -impact -impose -improve -impulse -inch -include -income -increase +hubraum +huehnerdieb +huf +hund +hygiene +hymne +hypnose +idee +ignoranz +imbiss +immobilie +import index -indicate -indoor -industry -infant -inflict -inform -inhale -inherit -initial -inject -injury -inmate -inner -innocent -input -inquiry -insane -insect -inside -inspire -install -intact -interest -into -invest -invite -involve -iron -island -isolate -issue -item -ivory -jacket +indianer +indikator +induktion +industrie +infarkt +infekt +infektion +inferno +information +inka +inkasso +innovation +innsbruck +insasse +insekt +insekten +insel +inselstaat +instanz +instinkt +institut +instrument +intelligenz +intellekt +interesse +irak +iran +irrenhaus +irrsinn +irrtum +italien +ivan +jacht +jachtklub +jacke +jacob +jagd jaguar -jar +jahr +jahrbuchs +jahre +jahrmarkt +jahrzehnt +japan jazz -jealous -jeans -jelly -jewel -job -join -joke -journey -joy -judge -juice -jump -jungle -junior -junk -just -kangaroo -keen -keep -ketchup -key -kick -kid -kidney +jazzband +joker +jongleur +jordanien +josef +jubel +jucken +judo +judoka +jugend +junge +jurist +kabarett +kabel +kabine +kabrio +kabriolett +kabuki +kabul +kadaver +kader +kaernten +kaese +kaffee +kafka +kairo +kaiser +kakao +kaktee +kaktus +kalabrien +kalauer +kalb +kali +kalk +kalkulation +kalkutta +kalzium +kambodscha +kamel +kamera +kamerad +kamikaze +kamille +kamin +kanada +kanaille +kanal +kannibale +kanzlei +kapitol +kapitulation +kaplan +kappe +kapsel +kapuze +karambolage +karate +karosse +karosserie +karotte +karriere +karte +kartei +kartell +kartenspiel +Kartoffel +kartoffelbrei +karton +kasino +kaskade +kasko +kasse +kassel +kastanie +kastell +katamaran +katastrophe +katze +katzenauge +kehle +keim +kennziffer +kent +kentucky +keramik +kerbe +kerbel +kessel +kette +ketzer +keule +kiesgrube +killer +kilo +kilogramm +kilometer +kilowatt kind -kingdom -kiss -kit -kitchen -kite -kitten -kiwi -knee -knife -knock -know -lab -label +kinder +kirchturm +kirschbaum +kirsche +kitzel +klamotten +klang +klar +klarheit +klarinette +klartext +klassik +klausel +klavier +klee +kleider +klima +klinik +klischee +klo +klopapier +kloster +klotz +klub +knallfrosch +kneipe +knete +knetmasse +knick +knie +kniff +knoblauch +knochen +knopf +knopfloch +knospe +kobalt +kobold +kobra +kochbuch +koerper +koffein +koffer +kohle +kokain +kollege +kombi +kombination +komma +kommandant +kommando +kommentar +kommerz +kommissar +kommode +kommune +kompetenz +komplott +kompost +konfekt +konfetti +konflikt +kongo +konkurs +konrad +konsens +konsulat +konvoi +kopfball +kopie +kork +kottelet +krabbe +krach +kraehe +kraft +kraftakt +krakau +kralle +kram +krampf +kran +krankenhaus +krebs +kredit +krefeld +kreide +kreis +krempe +krempel +kreole +kresse +kreta +kreuz +kreuzberg +kreuzung +krieg +krim +krimi +kriminalbeamte +kriminalbeamtin +krippe +krise +krishna +kristall +kritik +kuba +kubanerin +kuckuck +kueche +kufe +kugel +kugellager +kultur +kumulation +kundin +kundschaft +kunst +kurbel +kurbelwelle +kybernetik labor -ladder -lady -lake -lamp -language -laptop -large -later -latin -laugh -laundry +laborant +laborleiter +labrador +labyrinth +lachs +laderaum +ladung +lage +lager +lagune +lamborghini +lamelle +lametta +lamm +lampe +landau +landgut +landung +landzunge +langeweile +languste +lanzarote +last +lauch +lauge +laune +lautsprecher lava -law -lawn -lawsuit -layer -lazy -leader -leaf -learn -leave -lecture -left -leg -legal -legend -leisure -lemon -lend -length -lens +lavendel +lawine +layout +lazarett +legierung +legion +leguan +lehre +lehrer +leiche +leierkasten +leim +leine +leinen +leinwand +leitern +lektion +lektorin +lemming +leonie +leonore leopard -lesson -letter -level -liar -liberty -library -license -life -lift -light -like -limb -limit -link -lion -liquid -list -little -live -lizard -load -loan -lobster -local -lock -logic -lonely -long -loop -lottery -loud -lounge -love -loyal -lucky -luggage -lumber -lunar -lunch -luxury -lyrics -machine -mad -magic -magnet -maid -mail -main -major -make -mammal -man -manage -mandate -mango -mansion -manual -maple -marble -march -margin +leopold +lerche +lermming +lettland +leuchtturm +libanon +libelle +libyen +licht +lichtung +lid +liebe +lied +lieferung +limonade +linienbus +linsensuppe +linz +lippe +lizenz +lorbeer +loreley +lorenzo +luder +ludwigshafen +luebeck +luegner +luegnerin +luemmel +lueneburg +luft +luftabwehr +lugano +luke +luna +luxus +macher +macht +machtwort +macke +madonna +madrid +maedchen +mafia +magazin +magnetspule +mai +mainz +mais +maiskolben +malaria +malediven +maler +mammon +mammut +mandel +mandelbaum +manitu +manko +mann +manschette +mantel +manuela +marburg marine -market -marriage -mask -mass -master -match +marita +mark +markt +marmor +marokko +marquise +marrakesch +mars +mascarpone +masche +maschine +maschinenbau material -math -matrix -matter -maximum -maze -meadow -mean -measure -meat -mechanic -medal -media -melody -melt -member -memory -mention -menu -mercy -merge -merit -merry -mesh -message -metal -method -middle -midnight -milk -million -mimic -mind -minimum -minor -minute -miracle -mirror -misery -miss -mistake -mix -mixed -mixture -mobile -model -modify -mom -moment -monitor -monkey -monster -month -moon -moral -more -morning -mosquito -mother -motion +materie +mathematik +matratze +medikament +medizin +meer +melodie +melone +mensch +mercedes +merkmal +metall +metropole +metropolis +metzger +michelangelo +migraene +mikado +minderheit +mineral +minus +module +moebel +mondlandung motor -mountain -mouse -move -movie -much -muffin -mule -multiply -muscle +motorblock +muecke +muenze +muschi museum -mushroom -music -must -mutual -myself -mystery -myth -naive -name -napkin -narrow -nasty -nation -nature -near -neck -need -negative -neglect -neither -nephew -nerve -nest -net -network -neutral -never -news -next -nice -night -noble -noise -nominee -noodle +mustang +mutation +mutti +nachbar +nachricht +nachtleben +nadelholz +nagasaki +nagel +nagellack +nahrung +nairobi +nase +nasenbein +nationalpark +natur +nazi +neapel +nebel +nebraska +nebukadnezar +neckar +neffe +negativ +nepal +netz +netzanschluss +neubau +neujahrstag +neumond +neun +nickel +nie +niete +nikolaus +nikotin +nordpol +norm normal -north -nose -notable -note -nothing -notice -novel -now -nuclear -number -nurse -nut -oak -obey -object -oblige -obscure -observe -obtain -obvious -occur -ocean -october -odor -off -offer -office -often -oil -okay -old -olive -olympic -omit -once -one -onion -online -only -open -opera -opinion -oppose -option +normanne +norwegen +nostalgie +not +notar +notausgang +nudel +nudelholz +nylon +oberst +oberteil +objekt +obligation +ofen +ofenheizung +ohren +oktober +oldtimer +oleg +olga +oligarch +oliven +oliver +olymp +olympia +opa +opel +operette +oper +opium +opiumkrieg +optiker +opus orange -orbit -orchard -order -ordinary -organ +orden +ordner +ordnung +oregon +organe +organen +organleiden +orgel orient -original -orphan -ostrich -other -outdoor -outer -output -outside -oval -oven -over -own -owner -oxygen -oyster -ozone -pact -paddle +orion +orkan +orlando +orleans +ornament +ortschaft +oscar +osiris +oskar +oslo +osnabrueck +ostern +otter +otto +ouvertuere +ovation +ozean +ozeandampfer +ozonschicht +paella +paganini page -pair -palace -palm -panda -panel -panic -panther -paper -parade -parent +paket +palaver +palermo +palette +palisade +palladium +panzerkreuzer +panzer +papa +papagalli +papagallo +papagei +papierkorb +pappe +pappeln +paradies +paraguay +parameter +parasit +pardon +parfuem park -parrot +parkallee +parkhaus +parkplatz +parkuhr +parkverbot +parlament +parole +paroli +partei party -pass -patch -path +partyraum +paruguay +parzelle +passau +passfoto +patent patient -patrol -pattern -pause -pave -payment -peace -peanut -pear -peasant -pelican -pen -penalty -pencil -people -pepper -perfect -permit +paul +paulette +paulus +pauschal +pavian +pavillon +pazifik +pelikan +pellkartoffel +pelz +peng person -pet -phone +peru +peruecke +perversion +pest +peter +petersilie +pfadfinder +pfalz +pfand +pfannkuchen +pfarrer +pfeil +pferch +pferd +pfirsich +pflaster +pflasters +pflegerin +pfoertner +phaenomen +phalanx +phantast +pharao +pharma +pharmazie +phase +phasen +philippsburg +philosoph +philosphie +phlegma +phon +phonetik photo -phrase -physical -piano -picnic -picture -piece -pig -pigeon -pill -pilot -pink -pioneer -pipe -pistol -pitch -pizza -place -planet -plastic -plate -play -please -pledge -pluck -plug -plunge -poem -poet -point -polar -pole +pianist +piazza +picasso +pickelgesicht +picknick +piemont +pietaet +pigment +pils +pingpong +pinguin +pinie +pinsel +pinselstrich +pinzette +pionier +pirat +piraten +pirelli +pirmasens +piroschka +plagiat +plagiator +plakat +plankton +planquadrat +planzahl +plasma +plastik +plateau +platin +pluralismus +plus +plutarch +pluto +plutonium +plymouth +pokalsieg +pokerspiel +pol +polareis +polarfuchs +polaris police -pond -pony -pool -popular -portion +polier +poliklinik +politur +polle +pollen +pomp +pompadour +pompeij +pomps +porsche +portwein +porzellan position -possible post -potato -pottery -poverty -powder -power -practice -praise -predict -prefer -prepare -present -pretty -prevent -price -pride -primary -print -priority -prison -private -prize +poster +postfach +postille +postkarte +potzblitz +praefekt +praeparat +praxis +prellung +premier +premiere +presse +priester problem -process -produce +produkt +produzent +profession +professor +professur +profiboxer +profil +profilneurose profit -program -project -promote -proof -property -prosper -protect -proud -provide -public -pudding -pull -pulp -pulse -pumpkin -punch -pupil -puppy -purchase -purity -purpose -purse -push -put -puzzle -pyramid -quality -quantum -quarter -question -quick -quit +prognose +programm +projekt +projektion +prokura +promille +prominenz +propeller +prophet +provision +pruefung +pruegel +puffer +punsch +pupillen +puppe +pyjama +pyramide +qualitaet +qualle +qualm +quartal +quasar +quatsch +quattro +quebec +quitte +quitten +quittungen quiz -quote -rabbit -raccoon -race -rack +rabe +rache +racheakt radar -radio -rail -rain -raise -rally -ramp -ranch -random -range -rapid -rare -rate -rather -raven -raw -razor -ready +radarschirm +radioskop +radium +raetsel +raffinerie +raffinesse +rahm +rahmen +rampe +rampenlicht +rang +rasse +rastatt +raster +rastplatz +ratte +rattengift +raudi +raumschiff +rauschgift +ravenna +ravensberg real -reason -rebel -rebuild -recall -receive -recipe -record -recycle -reduce -reflect -reform -refuse -region -regret -regular -reject -relax -release -relief -rely -remain -remember -remind -remove -render -renew -rent -reopen -repair -repeat -replace -report -require -rescue -resemble -resist -resource -response -result -retire -retreat -return -reunion -reveal -review -reward -rhythm -rib -ribbon -rice -rich -ride -ridge -rifle -right -rigid -ring -riot -ripple -risk -ritual -rival -river -road -roast -robot -robust -rocket -romance -roof -rookie -room +reale +rebell +rechner +rechtsform +redner +reflektion +reflex +regal +regel +regenwald +regenwurm +reinfall +reis +reise +reiz +reklame +rekrut +reparatur +reporter +reporterin +reservat +reserve +reservebank +respekt +ressort +rettich +revolutuion +revolver +rhythmus +riad +rialto +ribbentrop +rind +risiko +rivale +rivalin +robbe +robert +roberta +robin +roboter +rolle rose -rotate -rough -round -route -royal -rubber -rude -rug -rule -run -runway -rural -sad -saddle -sadness -safe -sail -salad -salmon +rund +rundfunk +russe +spiegel +saatgut +sabotage +saboteur +sachbuch +sack +sackgasse +saeugling +safari +safran +saftladen +saite salon -salt -salute -same -sample -sand -satisfy -satoshi -sauce -sausage -save -say -scale -scan -scare -scatter -scene -scheme -school -science -scissors -scorpion -scout -scrap -screen -script -scrub -sea -search -season -seat -second -secret -section -security -seed -seek -segment -select -sell -seminar -senior -sense -sentence -series -service -session -settle -setup -seven -shadow -shaft -shallow -share -shed -shell -sheriff -shield -shift -shine -ship -shiver -shock -shoe -shoot -shop -short -shoulder -shove -shrimp -shrug -shuffle -shy -sibling -sick -side -siege -sight -sign -silent -silk -silly -silver -similar -simple -since -sing -siren -sister -situate -six -size -skate -sketch -ski -skill -skin -skirt -skull -slab -slam -sleep -slender -slice -slide -slight -slim -slogan -slot -slow -slush -small -smart -smile -smoke -smooth -snack -snake -snap -sniff -snow -soap -soccer -social -sock +saloniki +sambia +samen +samenbank +sammlung +sanddorn +sandsack +sanftmut +sansibar +sardine +sarg +sarkasmus +satan +satire +sattel +schachspiel +schach +schachtel +schaden +schafe +schandmaul +schanghai +scharade +schatten +schatulle +schatz +schatzamt +schaumbad +scheck +scheidung +schein +scheintod +scheitel +schenkel +scherbe +scherzartikel +schick +schickeria +schicksal +schiebedach +schiffbau +schild +schilf +schirm +schinken +schlachtschiff +schlamassel +schlamm +schlampe +schlauch +schlauchboot +schleim +schlitzohr +schloss +schlosser +schluckauf +schlummer +schmerz +schmerzen +schmuggler +schmusekatze +schmutz +schnake +schnaps +schnapsglas +schnapsidee +schneehase +schneekette +schnee +schnitzel +schnitzerei +schnulze +schnurrbart +schock +schotte +schrank +schranke +schreck +schreibpult +schritt +schrott +schuh +schulden +schuljahr +schuss +schuster +schutz +schwager +schwalbe +schwamm +schwan +schwinger +seebaer +seenot +segen +segler +seide +seife +semester +semikolon +sender +serie +sidnay +sie +sieben +sieger +siegerin +signatur +sigrid +sigrun +silbe +silber +simbabwe +simulant +sintflut +sinus +sinuskurve +sirene +sizilianer +skelett soda -soft -solar -soldier -solid -solution -solve -someone -song -soon -sorry -sort -soul -sound -soup -source -south -space -spare -spatial -spawn -speak -special -speed -spell -spend -sphere -spice -spider -spike -spin -spirit -split -spoil -sponsor -spoon +sodawasser +sodbrennen +sodomie +solarzelle +sommer +sommertag +sommerurlaub +sommerzeit +sonne +sonnenfleck +sonntag +spalt +spatel +spaten +specht +spekulation +sphinx +spiegel +spiel +spielbeginn +spinner +spinnrad +spion +spionin +spirale +spital +spitzmaus +spitzname +spleen +spore +sporn +sportbund sport -spot -spray -spread -spring -spy -square -squeeze -squirrel -stable +sportwagen +spreu +sprichwort +sprung +staat +staatsanwalt +staatsbesuch stadium -staff -stage -stairs -stamp +stadt +staffel +staffelei +stamm +stammaktie stand -start -state -stay +standard +statut +statuten +staub +stausee steak -steel -stem -step +steinmetz stereo -stick -still -sting -stock -stomach -stone -stool -story -stove -strategy -street -strike -strong -struggle -student -stuff -stumble -style -subject -submit -subway -success -such -sudden -suffer -sugar -suggest -suit -summer -sun -sunny -sunset -super -supply -supreme -sure -surface -surge -surprise -surround -survey -suspect -sustain -swallow -swamp -swap -swarm -swear -sweet -swift -swim -swing -switch -sword +sternbild +stettin +steuer +stichflamme +stift +strahl +strasse +sturmflut +sydney +sylt +sylvester +symbiose symbol symptom -syrup +syndikat system -table -tackle +szenario +taeter +tafel tag -tail +tagbau talent -talk +taler +talg +talgdruese +tanger +tango +tangs tank -tape -target -task +tankanlage +tankwart +tante +tanzbaer +tara +tarantel +tarif +taschendieb +tasse taste -tattoo +tatare +tartaria +tatendrang +tatort +tatze +tau +taube +taucher +tausch +tausend taxi -teach +taxifahrer team -tell -ten -tenant -tennis -tent -term -test +teamarbeit +technics +technikerin +teddybaer +teekanne +teenager +teheran +teich +teil +teilchen +teilnahme +teint +telefon +temperatur +teneriffa +tenor +teppich +termin +terminal +terrine +terror +texas text -thank -that -theme -then -theory -there -they -thing -this -thought -three -thrive -throw -thumb -thunder +thailand +theater +theke +thema +thematik +theo +theodor +theologe +theorie +therapeut +therapie +theresa +therese +thermalbad +thesaurus +these +thomas +thriller +thunfisch +thymian +tibet +tick ticket -tide -tiger -tilt -timber -time -tiny -tip -tired -tissue -title -toast -tobacco -today -toddler -toe -together -toilet -token -tomato -tomorrow -tone -tongue -tonight -tool -tooth -top -topic -topple -torch -tornado -tortoise -toss +tiegel +tier +tierarzt +tilsiter +tinte +tintenfass +tintenfisch +tintenfleck +tippzettel +tips +tirol +tischler +titan +titanic +titel +titelbild +tivoli +toaster +tobak +tobsucht +todfeind +tofu +toilette +tokio +toleranz +tollwut +tolpatsch +tomaten +tonlage +tonleiter +tonnage +tonne +tonspur +tor +torchance +torpedo +torpedoboot +torraum +tortur total +toulouse +tour +tourenrad tourist -toward -tower -town -toy -track -trade -traffic -tragic -train +tournee +toyota +trab +trabant +tracht +tradition +trafalgar +tragbahre +tragik +trainer +trakt +traktor +tramper +trance transfer -trap -trash -travel -tray -treat -tree +transport +trapez +tratte +trauer +traum +trauma +traumberuf +treffen +treffer +treiber +treibhaus +treibsand +treibstoff trend -trial -tribe +trennung +trennwand +treppe +tresen +tresor +treue +treueid +treuhand +tribun trick -trigger -trim -trip -trophy -trouble -truck -true -truly -trumpet -trust -truth -try -tube -tuition -tumble -tuna +trickfilm +triebwerk +triest +trikot +trilogie +trinkgeld +tripolis +tritt +triumpf +triumph +troja +trojaner +trommelfell +trommler +trompeter +tropen +trottel +trubel +truhe +truppe +tschernobyl +tuberkulose +tuebingen +tuemmler +tuer +tuerkei +tuete +tugend +tulpe +tumult +tundra +tunesien +tunichtgut tunnel -turkey -turn -turtle -twelve -twenty -twice -twin -twist -two +turban +turbine +turbo +turm +turner +turnerin +turnier +tusch +tycoon +typ type -typical -ugly -umbrella -unable -unaware -uncle -uncover -under -undo -unfair -unfold -unhappy +typografie +tyrann +tyrannei +ufo +uebung +ufer +uganda +uhrwerk +uhrzeit +uhu +ukraine +umfrage +umkehr +umkreis +umleitung +umschau +umschrift +umschweif +umweg +umzug +unfall +unfug +ungarn +ungeduld +ungeheuer +unhold uniform -unique -unit -universe -unknown -unlock -until -unusual -unveil -update -upgrade -uphold -upon -upper -upset -urban -urge -usage -use -used -useful -useless -usual -utility -vacant -vacuum -vague -valid -valley -valve -van -vanish -vapor -various -vast -vault -vehicle -velvet -vendor -venture -venue +unikum +universal +universum +unterholz +unterleib +unternehmer +unterricht +untertan +unterteil +unzucht +uran +urkunde +urlaub +urmensch +urne +ursache +urteil +urwald +urwelt +urzeit +utopie +utrecht +vagabund +vampir +vandale +vanille +variation +vasall +vater +vatikan +vehemenz +vehikel +veilchen +vene +venedig +venezuela +ventilator +ventil +venus +verachtung +veranda verb -verify -version -very -vessel +verband +verbleib +verblendung +verbot +verbrecher +verbund +verdienst +verdun +verehrer +verein +verfall +verfasser +vergleich +verhalten +verhandlung +verkehr +verlag +verlust +verona +verputz +verrat +verse +vertrag +verwalter +verwalterin +verzehr +verzicht +verzug veteran -viable -vibrant -vicious -victory +veto +vetorecht +viadukt +vibration +victor video -view -village -vintage -violin -virtual -virus +vieh +viertel +vignette +viktoria +viktualie +villa +viola +violine +viper +viren +virginia visa -visit -visual -vital -vivid -vocal -voice -void -volcano -volume -vote -voyage -wage -wagon -wait -walk +visage +visier +vision +visum +vitamin +vitrine +vogel +vogt +vokabel +vokal +volk +volleyball +vollmond +volt +voltaire +vorbild +votum +voyeur +vulkan +wachs +wachtstum +wade +waehrung +waffe +waffel +wagemut +waggon +waise +wal +wald wall -walnut -want -warfare -warm -warrior -wash -wasp -waste -water -wave -way -wealth -weapon -wear -weasel -weather -web -wedding -weekend -weird -welcome -west -wet -whale -what -wheat -wheel -when -where -whip -whisper -wide -width -wife -wild -will -win -window -wine -wing -wink -winner +wallach +walter +walther +wand +wanne +warze +wassermann +weber +wecker +wehmut +weib +weinblatt +weizen +welle +welpe +welt +weltall +werbung +werft +werk +werkstoff +werktag +wermut +wert +wertung +werwolf +wesen +weser +wespe +wespennest +weste +westfalen +westwind +wette +wetter +whisky +wicht +wichtig +wickel +widder +widmung +wiedergabe +wiesel +wiener +wildwest +wille +willi +willy +wimpel +wimper +wind +windbeutel +windhose +windhund +winkel winter -wire -wisdom -wise -wish -witness +winterthur +wippe +wirbelwind +wirkung +wirrwarr +wirt +wirtshaus +wischer +witterung +witwe +witz +wladimir +woche +woelbung wolf -woman -wonder -wood -wool -word -work -world -worry -worth -wrap -wreck -wrestle -wrist -write -wrong -yard -year -yellow -you -young -youth +wohnsitz +wohnung +wolfgang +wolfram +wolfsburg +wolfshund +wolke +wolga +wolle +wollust +worms +wort +wrack +wucher +wucht +wunde +wunder +wurf +wurm +wurzel +wut +xerox +xerxes +xylograph +yacht +yangtse +yen +yeti +yoga +yokohama +yuppie +zack +zaehler +zahl +zahn +zahnarzt +zahnaerztin +zahnersatz +zahnfleisch +zahngold +zahnluecke +zahnpaste +zahnpflege +zahnrad +zahnschmelz +zange +zapfenstreich +zar +zarathustra +zauber +zauberei +zaum +zaun +zaunkoenig zebra +zeche +zeh +zehner +zeichen +zeichnung +zeigefinger +zeiger +zeile +zeit +zeitalter +zeitbombe +zeitung +zeitgeist +zelle +zellkern +zeltdach +zelt +zement +zensur +zentner +zentral +zentrum +zeppelin +zepter +zeremonie +zerfall zero +zettel +zeuge +zeugin +zeus +zicke +ziege +ziegel +ziffer +zigarette +zigarillo +zigarre +zigeuner +zigeunerin +zikade +zimmer +zimmermann +zimt +zinne +zinnsoldat +zins +zirkel +zisterne +zitadelle +zitat +zivilist +zoll +zombie zone zoo +zopf +zorro +zucht +zucker +zuegel +zugabe +zukunft +zunge +zuruf +zustand +zuzug +zwang +zweifel +zwerg +zwerchfell +zwilling +zwinger +zwist +zyanid +zyankali +zyklon +zyklop +zyklus +zylinder +zyniker +zypern +zypresse + +zyste