From a1f86d502aba7f663128fb00f32231e4d8ff4725 Mon Sep 17 00:00:00 2001 From: dab246 Date: Sun, 24 Dec 2023 20:09:25 +0700 Subject: [PATCH] TF-2384 Handle NSE to get plain notification in iOS Signed-off-by: dab246 (cherry picked from commit 364f32a14b9888f73a3a103b8b5e1bc9b31e148e) --- ios/Podfile.lock | 12 +- ios/Runner.xcodeproj/project.pbxproj | 494 +++++++++++++++++- .../xcshareddata/swiftpm/Package.resolved | 23 + .../xcshareddata/swiftpm/Package.resolved | 23 + ios/Runner/AppDelegate.swift | 72 ++- ios/Runner/Runner.entitlements | 4 + ios/Runner/RunnerProfile.entitlements | 4 + ios/TwakeMailNSE/Info.plist | 17 + .../Keychain/KeyChainControllerDelegate.swift | 12 + .../Keychain/KeychainController.swift | 51 ++ .../Model/KeychainSharingSession.swift | 39 ++ ios/TwakeMailNSE/Model/TypeName.swift | 7 + ios/TwakeMailNSE/NotificationService.swift | 100 ++++ ios/TwakeMailNSE/TwakeMailNSE.entitlements | 14 + ios/TwakeMailNSE/Utils/BundleExtension.swift | 16 + ios/TwakeMailNSE/Utils/InfoPlistReader.swift | 45 ++ ios/TwakeMailNSE/Utils/PayloadParser.swift | 37 ++ model/lib/model.dart | 35 +- 18 files changed, 932 insertions(+), 73 deletions(-) create mode 100644 ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 ios/TwakeMailNSE/Info.plist create mode 100644 ios/TwakeMailNSE/Keychain/KeyChainControllerDelegate.swift create mode 100644 ios/TwakeMailNSE/Keychain/KeychainController.swift create mode 100644 ios/TwakeMailNSE/Model/KeychainSharingSession.swift create mode 100644 ios/TwakeMailNSE/Model/TypeName.swift create mode 100644 ios/TwakeMailNSE/NotificationService.swift create mode 100644 ios/TwakeMailNSE/TwakeMailNSE.entitlements create mode 100644 ios/TwakeMailNSE/Utils/BundleExtension.swift create mode 100644 ios/TwakeMailNSE/Utils/InfoPlistReader.swift create mode 100644 ios/TwakeMailNSE/Utils/PayloadParser.swift diff --git a/ios/Podfile.lock b/ios/Podfile.lock index ef7784111..c77bbf333 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -85,8 +85,6 @@ PODS: - fk_user_agent (2.0.0): - Flutter - Flutter (1.0.0) - - flutter_app_badger (1.3.0): - - Flutter - flutter_appauth (0.0.1): - AppAuth (= 1.6.2) - Flutter @@ -110,6 +108,8 @@ PODS: - Flutter - flutter_native_splash (0.0.1): - Flutter + - flutter_secure_storage (6.0.0): + - Flutter - GoogleDataTransport (9.2.1): - GoogleUtilities/Environment (~> 7.7) - nanopb (< 2.30910.0, >= 2.30908.0) @@ -191,7 +191,6 @@ DEPENDENCIES: - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - fk_user_agent (from `.symlinks/plugins/fk_user_agent/ios`) - Flutter (from `Flutter`) - - flutter_app_badger (from `.symlinks/plugins/flutter_app_badger/ios`) - flutter_appauth (from `.symlinks/plugins/flutter_appauth/ios`) - flutter_downloader (from `.symlinks/plugins/flutter_downloader/ios`) - flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`) @@ -199,6 +198,7 @@ DEPENDENCIES: - flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`) + - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) @@ -251,8 +251,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/fk_user_agent/ios" Flutter: :path: Flutter - flutter_app_badger: - :path: ".symlinks/plugins/flutter_app_badger/ios" flutter_appauth: :path: ".symlinks/plugins/flutter_appauth/ios" flutter_downloader: @@ -267,6 +265,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/flutter_local_notifications/ios" flutter_native_splash: :path: ".symlinks/plugins/flutter_native_splash/ios" + flutter_secure_storage: + :path: ".symlinks/plugins/flutter_secure_storage/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: @@ -303,7 +303,6 @@ SPEC CHECKSUMS: FirebaseMessaging: e345b219fd15d325f0cf2fef28cb8ce00d851b3f fk_user_agent: 1f47ec39291e8372b1d692b50084b0d54103c545 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 - flutter_app_badger: b87fc231847b03b92ce1412aa351842e7e97932f flutter_appauth: cf9b928962105b2a64a9802585d1c8adaf3e0f46 flutter_downloader: b7301ae057deadd4b1650dc7c05375f10ff12c39 flutter_image_compress_common: ec1d45c362c9d30a3f6a0426c297f47c52007e3e @@ -311,6 +310,7 @@ SPEC CHECKSUMS: flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743 flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef + flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be GoogleDataTransport: ea169759df570f4e37bdee1623ec32a7e64e67c4 GoogleUtilities: c2bdc4cf2ce786c4d2e6b3bcfd599a25ca78f06f libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 6b5423470..7eb6d9230 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -17,6 +17,32 @@ F52F993027FD6EB900346091 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F52F992F27FD6EB900346091 /* ShareViewController.swift */; }; F52F993327FD6EB900346091 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F52F993127FD6EB900346091 /* MainInterface.storyboard */; }; F52F993727FD6EB900346091 /* TeamMailShareExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = F52F992D27FD6EB900346091 /* TeamMailShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F53D1E632B2DE80200051FD0 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = F53D1E622B2DE80200051FD0 /* Alamofire */; }; + F53D1E662B2DE8B800051FD0 /* AlamofireService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D1E652B2DE8B800051FD0 /* AlamofireService.swift */; }; + F53D1E682B2E1CAE00051FD0 /* JmapClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D1E672B2E1CAE00051FD0 /* JmapClient.swift */; }; + F53D1E6C2B2E208C00051FD0 /* Email.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D1E6B2B2E208C00051FD0 /* Email.swift */; }; + F53D1E782B2E2C7E00051FD0 /* JmapResponseObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D1E772B2E2C7E00051FD0 /* JmapResponseObject.swift */; }; + F53D1E7C2B2E35CC00051FD0 /* EmailAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D1E7B2B2E35CC00051FD0 /* EmailAddress.swift */; }; + F53D1E7F2B2E3C2600051FD0 /* JmapConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D1E7E2B2E3C2600051FD0 /* JmapConstants.swift */; }; + F53D1E832B2E3D4600051FD0 /* JmapRequestObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D1E822B2E3D4600051FD0 /* JmapRequestObject.swift */; }; + F53D1E862B2E401B00051FD0 /* JmapRequestGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D1E852B2E401B00051FD0 /* JmapRequestGenerator.swift */; }; + F53D1E882B2E4B3B00051FD0 /* AuthenticationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D1E872B2E4B3B00051FD0 /* AuthenticationType.swift */; }; + F53D1E8A2B2E4BB700051FD0 /* TokenOidc.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D1E892B2E4BB700051FD0 /* TokenOidc.swift */; }; + F5630C762B2CDFDA003CC0FD /* KeychainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5630C752B2CDFDA003CC0FD /* KeychainController.swift */; }; + F5630C782B2CE091003CC0FD /* KeyChainControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5630C772B2CE091003CC0FD /* KeyChainControllerDelegate.swift */; }; + F5630C7B2B2CE148003CC0FD /* KeychainSharingSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5630C7A2B2CE148003CC0FD /* KeychainSharingSession.swift */; }; + F5630C7E2B2CE359003CC0FD /* InfoPlistReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5630C7D2B2CE359003CC0FD /* InfoPlistReader.swift */; }; + F5630C812B2CEBC0003CC0FD /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = F5630C802B2CEBC0003CC0FD /* KeychainAccess */; }; + F5630C852B2CF50C003CC0FD /* TypeName.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5630C842B2CF50C003CC0FD /* TypeName.swift */; }; + F5630C872B2D0387003CC0FD /* PayloadParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5630C862B2D0387003CC0FD /* PayloadParser.swift */; }; + F5BBBF512B2EEC37007930E1 /* NetworkExceptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5BBBF502B2EEC37007930E1 /* NetworkExceptions.swift */; }; + F5BBBF532B2EECAA007930E1 /* JmapExceptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5BBBF522B2EECAA007930E1 /* JmapExceptions.swift */; }; + F5BBBF552B2EEF3D007930E1 /* BundleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5BBBF542B2EEF3D007930E1 /* BundleExtension.swift */; }; + F5D4EA032B2ABF090090DDFC /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5D4EA022B2ABF090090DDFC /* NotificationService.swift */; }; + F5D4EA072B2ABF090090DDFC /* TwakeMailNSE.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = F5D4EA002B2ABF090090DDFC /* TwakeMailNSE.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F5EFC07D2B328B9F00829056 /* TwakeLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5EFC07C2B328B9F00829056 /* TwakeLogger.swift */; }; + F5EFC07E2B328B9F00829056 /* TwakeLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5EFC07C2B328B9F00829056 /* TwakeLogger.swift */; }; + F5EFC07F2B3292FA00829056 /* TwakeLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5EFC07C2B328B9F00829056 /* TwakeLogger.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -27,6 +53,13 @@ remoteGlobalIDString = F52F992C27FD6EB900346091; remoteInfo = TeamMailShareExtension; }; + F5D4EA052B2ABF090090DDFC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = F5D4E9FF2B2ABF090090DDFC; + remoteInfo = TwakeMailNSE; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -47,6 +80,7 @@ dstSubfolderSpec = 13; files = ( F52F993727FD6EB900346091 /* TeamMailShareExtension.appex in Embed App Extensions */, + F5D4EA072B2ABF090090DDFC /* TwakeMailNSE.appex in Embed App Extensions */, ); name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; @@ -78,6 +112,30 @@ F52F993427FD6EB900346091 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F52F993D27FD733C00346091 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; F52F993E27FD741100346091 /* TeamMailShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TeamMailShareExtension.entitlements; sourceTree = ""; }; + F53D1E652B2DE8B800051FD0 /* AlamofireService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlamofireService.swift; sourceTree = ""; }; + F53D1E672B2E1CAE00051FD0 /* JmapClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JmapClient.swift; sourceTree = ""; }; + F53D1E6B2B2E208C00051FD0 /* Email.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Email.swift; sourceTree = ""; }; + F53D1E772B2E2C7E00051FD0 /* JmapResponseObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JmapResponseObject.swift; sourceTree = ""; }; + F53D1E7B2B2E35CC00051FD0 /* EmailAddress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailAddress.swift; sourceTree = ""; }; + F53D1E7E2B2E3C2600051FD0 /* JmapConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JmapConstants.swift; sourceTree = ""; }; + F53D1E822B2E3D4600051FD0 /* JmapRequestObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JmapRequestObject.swift; sourceTree = ""; }; + F53D1E852B2E401B00051FD0 /* JmapRequestGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JmapRequestGenerator.swift; sourceTree = ""; }; + F53D1E872B2E4B3B00051FD0 /* AuthenticationType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationType.swift; sourceTree = ""; }; + F53D1E892B2E4BB700051FD0 /* TokenOidc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenOidc.swift; sourceTree = ""; }; + F5630C752B2CDFDA003CC0FD /* KeychainController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainController.swift; sourceTree = ""; }; + F5630C772B2CE091003CC0FD /* KeyChainControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyChainControllerDelegate.swift; sourceTree = ""; }; + F5630C7A2B2CE148003CC0FD /* KeychainSharingSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainSharingSession.swift; sourceTree = ""; }; + F5630C7D2B2CE359003CC0FD /* InfoPlistReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoPlistReader.swift; sourceTree = ""; }; + F5630C842B2CF50C003CC0FD /* TypeName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeName.swift; sourceTree = ""; }; + F5630C862B2D0387003CC0FD /* PayloadParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayloadParser.swift; sourceTree = ""; }; + F5BBBF502B2EEC37007930E1 /* NetworkExceptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkExceptions.swift; sourceTree = ""; }; + F5BBBF522B2EECAA007930E1 /* JmapExceptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JmapExceptions.swift; sourceTree = ""; }; + F5BBBF542B2EEF3D007930E1 /* BundleExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleExtension.swift; sourceTree = ""; }; + F5D4EA002B2ABF090090DDFC /* TwakeMailNSE.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = TwakeMailNSE.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + F5D4EA022B2ABF090090DDFC /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; + F5D4EA042B2ABF090090DDFC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F5D4EA0C2B2ABF970090DDFC /* TwakeMailNSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TwakeMailNSE.entitlements; sourceTree = ""; }; + F5EFC07C2B328B9F00829056 /* TwakeLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwakeLogger.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -96,6 +154,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F5D4E9FD2B2ABF090090DDFC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F5630C812B2CEBC0003CC0FD /* KeychainAccess in Frameworks */, + F53D1E632B2DE80200051FD0 /* Alamofire in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -121,9 +188,11 @@ 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( + F5EFC0802B32965100829056 /* TwakeCore */, 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, F52F992E27FD6EB900346091 /* TeamMailShareExtension */, + F5D4EA012B2ABF090090DDFC /* TwakeMailNSE */, 97C146EF1CF9000F007C117D /* Products */, F62B48DC0DFBD6D5D355E5FE /* Pods */, 601CDD7C97AAAE9C3FB007DB /* Frameworks */, @@ -135,6 +204,7 @@ children = ( 97C146EE1CF9000F007C117D /* Runner.app */, F52F992D27FD6EB900346091 /* TeamMailShareExtension.appex */, + F5D4EA002B2ABF090090DDFC /* TwakeMailNSE.appex */, ); name = Products; sourceTree = ""; @@ -167,6 +237,147 @@ path = TeamMailShareExtension; sourceTree = ""; }; + F53D1E642B2DE84E00051FD0 /* Network */ = { + isa = PBXGroup; + children = ( + F5E7D8762B385B430009BB8A /* Model */, + F53D1E652B2DE8B800051FD0 /* AlamofireService.swift */, + ); + path = Network; + sourceTree = ""; + }; + F53D1E692B2E1F5100051FD0 /* Jmap */ = { + isa = PBXGroup; + children = ( + F53D1E842B2E3F5B00051FD0 /* Utils */, + F53D1E672B2E1CAE00051FD0 /* JmapClient.swift */, + F53D1E6A2B2E1F6700051FD0 /* Model */, + ); + path = Jmap; + sourceTree = ""; + }; + F53D1E6A2B2E1F6700051FD0 /* Model */ = { + isa = PBXGroup; + children = ( + F53D1E812B2E3D0300051FD0 /* Request */, + F53D1E802B2E3CF600051FD0 /* Response */, + F53D1E7D2B2E369300051FD0 /* Email */, + ); + path = Model; + sourceTree = ""; + }; + F53D1E7D2B2E369300051FD0 /* Email */ = { + isa = PBXGroup; + children = ( + F53D1E6B2B2E208C00051FD0 /* Email.swift */, + F53D1E7B2B2E35CC00051FD0 /* EmailAddress.swift */, + ); + path = Email; + sourceTree = ""; + }; + F53D1E802B2E3CF600051FD0 /* Response */ = { + isa = PBXGroup; + children = ( + F53D1E772B2E2C7E00051FD0 /* JmapResponseObject.swift */, + ); + path = Response; + sourceTree = ""; + }; + F53D1E812B2E3D0300051FD0 /* Request */ = { + isa = PBXGroup; + children = ( + F53D1E822B2E3D4600051FD0 /* JmapRequestObject.swift */, + ); + path = Request; + sourceTree = ""; + }; + F53D1E842B2E3F5B00051FD0 /* Utils */ = { + isa = PBXGroup; + children = ( + F53D1E7E2B2E3C2600051FD0 /* JmapConstants.swift */, + F53D1E852B2E401B00051FD0 /* JmapRequestGenerator.swift */, + ); + path = Utils; + sourceTree = ""; + }; + F5630C742B2CDFC5003CC0FD /* Keychain */ = { + isa = PBXGroup; + children = ( + F5630C752B2CDFDA003CC0FD /* KeychainController.swift */, + F5630C772B2CE091003CC0FD /* KeyChainControllerDelegate.swift */, + ); + path = Keychain; + sourceTree = ""; + }; + F5630C792B2CE133003CC0FD /* Model */ = { + isa = PBXGroup; + children = ( + F5630C7A2B2CE148003CC0FD /* KeychainSharingSession.swift */, + F5630C842B2CF50C003CC0FD /* TypeName.swift */, + ); + path = Model; + sourceTree = ""; + }; + F5630C7C2B2CE33A003CC0FD /* Utils */ = { + isa = PBXGroup; + children = ( + F5630C7D2B2CE359003CC0FD /* InfoPlistReader.swift */, + F5BBBF542B2EEF3D007930E1 /* BundleExtension.swift */, + F5630C862B2D0387003CC0FD /* PayloadParser.swift */, + ); + path = Utils; + sourceTree = ""; + }; + F5BBBF4F2B2EEC1B007930E1 /* Exceptions */ = { + isa = PBXGroup; + children = ( + F5BBBF502B2EEC37007930E1 /* NetworkExceptions.swift */, + F5BBBF522B2EECAA007930E1 /* JmapExceptions.swift */, + ); + path = Exceptions; + sourceTree = ""; + }; + F5D4EA012B2ABF090090DDFC /* TwakeMailNSE */ = { + isa = PBXGroup; + children = ( + F5630C7C2B2CE33A003CC0FD /* Utils */, + F5630C792B2CE133003CC0FD /* Model */, + F5630C742B2CDFC5003CC0FD /* Keychain */, + F5D4EA0C2B2ABF970090DDFC /* TwakeMailNSE.entitlements */, + F5D4EA022B2ABF090090DDFC /* NotificationService.swift */, + F5D4EA042B2ABF090090DDFC /* Info.plist */, + ); + path = TwakeMailNSE; + sourceTree = ""; + }; + F5E7D8762B385B430009BB8A /* Model */ = { + isa = PBXGroup; + children = ( + F53D1E872B2E4B3B00051FD0 /* AuthenticationType.swift */, + F53D1E892B2E4BB700051FD0 /* TokenOidc.swift */, + ); + path = Model; + sourceTree = ""; + }; + F5EFC07B2B328B8600829056 /* Logger */ = { + isa = PBXGroup; + children = ( + F5EFC07C2B328B9F00829056 /* TwakeLogger.swift */, + ); + path = Logger; + sourceTree = ""; + }; + F5EFC0802B32965100829056 /* TwakeCore */ = { + isa = PBXGroup; + children = ( + F5BBBF4F2B2EEC1B007930E1 /* Exceptions */, + F53D1E642B2DE84E00051FD0 /* Network */, + F5EFC07B2B328B8600829056 /* Logger */, + F53D1E692B2E1F5100051FD0 /* Jmap */, + ); + path = TwakeCore; + sourceTree = ""; + }; F62B48DC0DFBD6D5D355E5FE /* Pods */ = { isa = PBXGroup; children = ( @@ -198,6 +409,7 @@ ); dependencies = ( F52F993627FD6EB900346091 /* PBXTargetDependency */, + F5D4EA062B2ABF090090DDFC /* PBXTargetDependency */, ); name = Runner; productName = Runner; @@ -221,13 +433,34 @@ productReference = F52F992D27FD6EB900346091 /* TeamMailShareExtension.appex */; productType = "com.apple.product-type.app-extension"; }; + F5D4E9FF2B2ABF090090DDFC /* TwakeMailNSE */ = { + isa = PBXNativeTarget; + buildConfigurationList = F5D4EA0B2B2ABF090090DDFC /* Build configuration list for PBXNativeTarget "TwakeMailNSE" */; + buildPhases = ( + F5D4E9FC2B2ABF090090DDFC /* Sources */, + F5D4E9FD2B2ABF090090DDFC /* Frameworks */, + F5D4E9FE2B2ABF090090DDFC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TwakeMailNSE; + packageProductDependencies = ( + F5630C802B2CEBC0003CC0FD /* KeychainAccess */, + F53D1E622B2DE80200051FD0 /* Alamofire */, + ); + productName = TwakeMailNSE; + productReference = F5D4EA002B2ABF090090DDFC /* TwakeMailNSE.appex */; + productType = "com.apple.product-type.app-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1320; + LastSwiftUpdateCheck = 1510; LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { @@ -238,6 +471,9 @@ F52F992C27FD6EB900346091 = { CreatedOnToolsVersion = 13.2.1; }; + F5D4E9FF2B2ABF090090DDFC = { + CreatedOnToolsVersion = 15.1; + }; }; }; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; @@ -249,12 +485,17 @@ Base, ); mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + F5630C7F2B2CEBC0003CC0FD /* XCRemoteSwiftPackageReference "KeychainAccess" */, + F53D1E612B2DE80200051FD0 /* XCRemoteSwiftPackageReference "Alamofire" */, + ); productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, F52F992C27FD6EB900346091 /* TeamMailShareExtension */, + F5D4E9FF2B2ABF090090DDFC /* TwakeMailNSE */, ); }; /* End PBXProject section */ @@ -279,6 +520,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F5D4E9FE2B2ABF090090DDFC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -361,6 +609,7 @@ files = ( 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + F5EFC07D2B328B9F00829056 /* TwakeLogger.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -368,10 +617,39 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F5EFC07F2B3292FA00829056 /* TwakeLogger.swift in Sources */, F52F993027FD6EB900346091 /* ShareViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + F5D4E9FC2B2ABF090090DDFC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F5BBBF512B2EEC37007930E1 /* NetworkExceptions.swift in Sources */, + F53D1E7F2B2E3C2600051FD0 /* JmapConstants.swift in Sources */, + F5D4EA032B2ABF090090DDFC /* NotificationService.swift in Sources */, + F53D1E8A2B2E4BB700051FD0 /* TokenOidc.swift in Sources */, + F53D1E862B2E401B00051FD0 /* JmapRequestGenerator.swift in Sources */, + F5630C7E2B2CE359003CC0FD /* InfoPlistReader.swift in Sources */, + F53D1E662B2DE8B800051FD0 /* AlamofireService.swift in Sources */, + F5BBBF532B2EECAA007930E1 /* JmapExceptions.swift in Sources */, + F53D1E882B2E4B3B00051FD0 /* AuthenticationType.swift in Sources */, + F53D1E6C2B2E208C00051FD0 /* Email.swift in Sources */, + F5630C872B2D0387003CC0FD /* PayloadParser.swift in Sources */, + F53D1E782B2E2C7E00051FD0 /* JmapResponseObject.swift in Sources */, + F5630C852B2CF50C003CC0FD /* TypeName.swift in Sources */, + F5630C7B2B2CE148003CC0FD /* KeychainSharingSession.swift in Sources */, + F53D1E682B2E1CAE00051FD0 /* JmapClient.swift in Sources */, + F5BBBF552B2EEF3D007930E1 /* BundleExtension.swift in Sources */, + F53D1E7C2B2E35CC00051FD0 /* EmailAddress.swift in Sources */, + F5EFC07E2B328B9F00829056 /* TwakeLogger.swift in Sources */, + F5630C762B2CDFDA003CC0FD /* KeychainController.swift in Sources */, + F53D1E832B2E3D4600051FD0 /* JmapRequestObject.swift in Sources */, + F5630C782B2CE091003CC0FD /* KeyChainControllerDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -380,6 +658,11 @@ target = F52F992C27FD6EB900346091 /* TeamMailShareExtension */; targetProxy = F52F993527FD6EB900346091 /* PBXContainerItemProxy */; }; + F5D4EA062B2ABF090090DDFC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F5D4E9FF2B2ABF090090DDFC /* TwakeMailNSE */; + targetProxy = F5D4EA052B2ABF090090DDFC /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -469,10 +752,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = KUT463DS29; + DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; @@ -482,7 +765,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.linagora.ios.teammail; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = tmail.development.profile; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -605,10 +888,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = KUT463DS29; + DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; @@ -618,7 +901,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.linagora.ios.teammail; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = tmail.development.profile; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -635,12 +918,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CODE_SIGN_IDENTITY = "Apple Distribution"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = KUT463DS29; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = KUT463DS29; + DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; @@ -650,8 +931,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.linagora.ios.teammail; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = tmail.distribution.profile; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = tmail.distribution.profile; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -668,11 +948,10 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = TeamMailShareExtension/TeamMailShareExtension.entitlements; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = KUT463DS29; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = KUT463DS29; + DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = TeamMailShareExtension/Info.plist; @@ -689,8 +968,7 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.linagora.ios.teammail.TeamMailShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = tmail.share.ext.development.profile; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = tmail.share.ext.development.profile; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -710,12 +988,10 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = TeamMailShareExtension/TeamMailShareExtension.entitlements; - CODE_SIGN_IDENTITY = "Apple Distribution"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = KUT463DS29; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = KUT463DS29; + DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = TeamMailShareExtension/Info.plist; @@ -731,8 +1007,7 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.linagora.ios.teammail.TeamMailShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = tmail.share.ext.distribution.profile; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = tmail.share.ext.distribution.profile; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -750,10 +1025,10 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_ENTITLEMENTS = TeamMailShareExtension/TeamMailShareExtension.entitlements; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Manual; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = KUT463DS29; + DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = TeamMailShareExtension/Info.plist; @@ -769,7 +1044,130 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.linagora.ios.teammail.TeamMailShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = tmail.share.ext.development.profile; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Profile; + }; + F5D4EA082B2ABF090090DDFC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = TwakeMailNSE/TwakeMailNSE.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = TwakeMailNSE/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = TwakeMailNSE; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.linagora.ios.teammail.TwakeMailNSE; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F5D4EA092B2ABF090090DDFC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = TwakeMailNSE/TwakeMailNSE.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = TwakeMailNSE/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = TwakeMailNSE; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.linagora.ios.teammail.TwakeMailNSE; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F5D4EA0A2B2ABF090090DDFC /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = TwakeMailNSE/TwakeMailNSE.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = TwakeMailNSE/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = TwakeMailNSE; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.linagora.ios.teammail.TwakeMailNSE; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -810,7 +1208,49 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + F5D4EA0B2B2ABF090090DDFC /* Build configuration list for PBXNativeTarget "TwakeMailNSE" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F5D4EA082B2ABF090090DDFC /* Debug */, + F5D4EA092B2ABF090090DDFC /* Release */, + F5D4EA0A2B2ABF090090DDFC /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + F53D1E612B2DE80200051FD0 /* XCRemoteSwiftPackageReference "Alamofire" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Alamofire/Alamofire.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.8.1; + }; + }; + F5630C7F2B2CEBC0003CC0FD /* XCRemoteSwiftPackageReference "KeychainAccess" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess.git"; + requirement = { + branch = master; + kind = branch; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + F53D1E622B2DE80200051FD0 /* Alamofire */ = { + isa = XCSwiftPackageProductDependency; + package = F53D1E612B2DE80200051FD0 /* XCRemoteSwiftPackageReference "Alamofire" */; + productName = Alamofire; + }; + F5630C802B2CEBC0003CC0FD /* KeychainAccess */ = { + isa = XCSwiftPackageProductDependency; + package = F5630C7F2B2CEBC0003CC0FD /* XCRemoteSwiftPackageReference "KeychainAccess" */; + productName = KeychainAccess; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 000000000..70b7faba4 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,23 @@ +{ + "pins" : [ + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire.git", + "state" : { + "revision" : "3dc6a42c7727c49bf26508e29b0a0b35f9c7e1ad", + "version" : "5.8.1" + } + }, + { + "identity" : "keychainaccess", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kishikawakatsumi/KeychainAccess.git", + "state" : { + "branch" : "master", + "revision" : "e0c7eebc5a4465a3c4680764f26b7a61f567cdaf" + } + } + ], + "version" : 2 +} diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 000000000..70b7faba4 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,23 @@ +{ + "pins" : [ + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire.git", + "state" : { + "revision" : "3dc6a42c7727c49bf26508e29b0a0b35f9c7e1ad", + "version" : "5.8.1" + } + }, + { + "identity" : "keychainaccess", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kishikawakatsumi/KeychainAccess.git", + "state" : { + "branch" : "master", + "revision" : "e0c7eebc5a4465a3c4680764f26b7a61f567cdaf" + } + } + ], + "version" : 2 +} diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 0b33c5192..961882587 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -6,29 +6,19 @@ import flutter_local_notifications @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { - - /// Registers all pubspec-referenced Flutter plugins in the given registry. - static func registerPlugins(with registry: FlutterPluginRegistry) { - GeneratedPluginRegistrant.register(with: registry) - } - + override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - /// Register the app's plugins in the context of a normal run - AppDelegate.registerPlugins(with: self) - - UNUserNotificationCenter.current().delegate = self + GeneratedPluginRegistrant.register(with: self) if #available(iOS 10.0, *) { UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate } - UIApplication.shared.setMinimumBackgroundFetchInterval(TimeInterval(60*15)) - FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { registry in - AppDelegate.registerPlugins(with: registry) + GeneratedPluginRegistrant.register(with: registry) } FlutterDownloaderPlugin.setPluginRegistrantCallback { registry in @@ -62,14 +52,12 @@ import flutter_local_notifications return sharingIntent.application(app, open: url, options: options) } } - // For example load MSALPublicClientApplication - // return MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: options[.sourceApplication] as? String) - - // Cancel url handling - // return false - - // Proceed url handling for other Flutter libraries like uni_links - return super.application(app, open: url, options:options) + + return super.application(app, open: url, options:options) + } + + override func applicationDidBecomeActive(_ application: UIApplication) { + removeAppBadger() } private func handleEmailAndress(open url: URL) -> URL? { @@ -86,9 +74,49 @@ import flutter_local_notifications return URL(string: "ShareMedia-\(appDomain)://dataUrl=\(sharedKey)#text") } + // Receive displayed notifications for iOS 10 or later devices. override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { - completionHandler(.alert) // shows banner even if app is in foreground + TwakeLogger.shared.log(message: "AppDelegate::userNotificationCenter::willPresent::notification: \(notification)") + if let notificationBadgeCount = notification.request.content.badge?.intValue, notificationBadgeCount > 0 { + let newBadgeCount = UIApplication.shared.applicationIconBadgeNumber + notificationBadgeCount + TwakeLogger.shared.log(message: "AppDelegate::userNotificationCenter::willPresent:newBadgeCount: \(newBadgeCount)") + updateAppBadger(currentBadgeCount: newBadgeCount) + } + + completionHandler(isAppForegroundActive() ? [] : [.alert, .badge, .sound]) + } + + override func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { + updateAppBadger(currentBadgeCount: UIApplication.shared.applicationIconBadgeNumber) + completionHandler() + } +} + +extension AppDelegate { + private func updateAppBadger(currentBadgeCount: Int) { + let newBadgeCount = currentBadgeCount > 0 ? currentBadgeCount - 1 : 0 + TwakeLogger.shared.log(message: "AppDelegate::updateAppBadger::newBadgeCount: \(newBadgeCount)") + if #available(iOS 16.0, *) { + UNUserNotificationCenter.current().setBadgeCount(newBadgeCount) + } else { + UIApplication.shared.applicationIconBadgeNumber = newBadgeCount + + } + } + + private func removeAppBadger() { + TwakeLogger.shared.log(message: "AppDelegate::removeAppBadger") + if #available(iOS 16.0, *) { + UNUserNotificationCenter.current().setBadgeCount(0) + } else { + UIApplication.shared.applicationIconBadgeNumber = 0 + + } + } + + private func isAppForegroundActive() -> Bool { + return UIApplication.shared.applicationState == .active } } diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index 1a519d635..171776246 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -8,5 +8,9 @@ group.com.linagora.teammail + keychain-access-groups + + $(AppIdentifierPrefix)com.linagora.ios.teammail.shared + diff --git a/ios/Runner/RunnerProfile.entitlements b/ios/Runner/RunnerProfile.entitlements index 1a519d635..171776246 100644 --- a/ios/Runner/RunnerProfile.entitlements +++ b/ios/Runner/RunnerProfile.entitlements @@ -8,5 +8,9 @@ group.com.linagora.teammail + keychain-access-groups + + $(AppIdentifierPrefix)com.linagora.ios.teammail.shared + diff --git a/ios/TwakeMailNSE/Info.plist b/ios/TwakeMailNSE/Info.plist new file mode 100644 index 000000000..05d36c34d --- /dev/null +++ b/ios/TwakeMailNSE/Info.plist @@ -0,0 +1,17 @@ + + + + + keychainAccessGroupIdentifier + KUT463DS29.com.linagora.ios.teammail.shared + baseBundleIdentifier + com.linagora.ios.teammail + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + + diff --git a/ios/TwakeMailNSE/Keychain/KeyChainControllerDelegate.swift b/ios/TwakeMailNSE/Keychain/KeyChainControllerDelegate.swift new file mode 100644 index 000000000..5143f7fe5 --- /dev/null +++ b/ios/TwakeMailNSE/Keychain/KeyChainControllerDelegate.swift @@ -0,0 +1,12 @@ +import Foundation + +struct KeychainCredentials { + let accountId: String + let sharingSession: KeychainSharingSession +} + +protocol KeychainControllerDelegate: AnyObject { + func retrieveSharingSessionFromKeychain(accountId: String) -> KeychainSharingSession? + func retrieveSharingSessions() -> [KeychainCredentials] + func updateEmailStateToKeychain(accountId: String, newState: String) +} diff --git a/ios/TwakeMailNSE/Keychain/KeychainController.swift b/ios/TwakeMailNSE/Keychain/KeychainController.swift new file mode 100644 index 000000000..eb15d2611 --- /dev/null +++ b/ios/TwakeMailNSE/Keychain/KeychainController.swift @@ -0,0 +1,51 @@ +import Foundation +import KeychainAccess + +enum KeychainControllerService: String { + case sessions + + var identifier: String { + InfoPlistReader.main.baseBundleIdentifier + "." + rawValue + } +} + +class KeychainController: KeychainControllerDelegate { + private let keychain: Keychain + + init(service: KeychainControllerService, + accessGroup: String) { + keychain = Keychain(service: service.identifier, + accessGroup: accessGroup) + } + + func retrieveSharingSessionFromKeychain(accountId: String) -> KeychainSharingSession? { + do { + guard let sessionData = try keychain.getData(accountId) else { + return nil + } + + return try JSONDecoder().decode(KeychainSharingSession.self, from: sessionData) + } catch { + return nil + } + } + + func retrieveSharingSessions() -> [KeychainCredentials] { + keychain.allKeys().compactMap { accountId in + guard let sharingSession = retrieveSharingSessionFromKeychain(accountId: accountId) else { + return nil + } + + return KeychainCredentials(accountId: accountId, sharingSession: sharingSession) + } + } + + func updateEmailStateToKeychain(accountId: String, newState: String) { + do { + if let sharingSession = retrieveSharingSessionFromKeychain(accountId: accountId) { + let newSharingSession = sharingSession.updateEmailState(newState: newState) + try keychain.set(newSharingSession.toJson() ?? "", key: accountId) + } + } catch {} + } +} diff --git a/ios/TwakeMailNSE/Model/KeychainSharingSession.swift b/ios/TwakeMailNSE/Model/KeychainSharingSession.swift new file mode 100644 index 000000000..35f8e43c5 --- /dev/null +++ b/ios/TwakeMailNSE/Model/KeychainSharingSession.swift @@ -0,0 +1,39 @@ +import Foundation + +struct KeychainSharingSession: Codable { + let accountId: String + let userName: String + let authenticationType: AuthenticationType + let apiUrl: String + let emailState: String? + let tokenOIDC: TokenOidc? + let basicAuth: String? +} + +extension KeychainSharingSession { + func updateEmailState(newState: String) -> KeychainSharingSession { + return KeychainSharingSession( + accountId: self.accountId, + userName: self.userName, + authenticationType: self.authenticationType, + apiUrl: self.apiUrl, + emailState: newState, + tokenOIDC: self.tokenOIDC, + basicAuth: self.basicAuth + ) + } + + func toData() -> Data? { + if let encodedData = try? JSONEncoder().encode(self) { + return encodedData + } + return nil + } + + func toJson() -> String? { + if let data = toData(), let jsonString = String(data: data, encoding: .utf8) { + return jsonString + } + return nil + } +} diff --git a/ios/TwakeMailNSE/Model/TypeName.swift b/ios/TwakeMailNSE/Model/TypeName.swift new file mode 100644 index 000000000..a276e6cd7 --- /dev/null +++ b/ios/TwakeMailNSE/Model/TypeName.swift @@ -0,0 +1,7 @@ +import Foundation + +enum TypeName: String { + case mailbox = "Mailbox" + case email = "Email" + case EmailDelivery = "EmailDelivery" +} diff --git a/ios/TwakeMailNSE/NotificationService.swift b/ios/TwakeMailNSE/NotificationService.swift new file mode 100644 index 000000000..50685f501 --- /dev/null +++ b/ios/TwakeMailNSE/NotificationService.swift @@ -0,0 +1,100 @@ +import UserNotifications + +class NotificationService: UNNotificationServiceExtension { + + private var handler: ((UNNotificationContent) -> Void)? + private var modifiedContent: UNMutableNotificationContent? + + private lazy var keychainController = KeychainController(service: .sessions, + accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier) + + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { + guard let payloadData = request.content.userInfo as? [String: Any], + !keychainController.retrieveSharingSessions().isEmpty else { + return self.discard() + } + + handler = contentHandler + modifiedContent = (request.content.mutableCopy() as? UNMutableNotificationContent) + + self.modifiedContent?.title = InfoPlistReader(bundle: .app).bundleDisplayName + + Task { + await handleGetNewEmails(payloadData: payloadData) + } + } + + + override func serviceExtensionTimeWillExpire() { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + notify() + } + + private func handleGetNewEmails(payloadData: [String: Any]) async { + let mapStateChanges: [String: [TypeName: String]] = PayloadParser.shared.parsingPayloadNotification(payloadData: payloadData) + + if (mapStateChanges.isEmpty) { + return self.discard() + } else { + guard let currentAccountId = mapStateChanges.keys.first, + let keychainSharingSession = keychainController.retrieveSharingSessionFromKeychain(accountId: currentAccountId), + let listStateOfAccount = mapStateChanges[currentAccountId], + let newEmailState = listStateOfAccount[TypeName.EmailDelivery], + let oldEmailState = keychainSharingSession.emailState, + newEmailState != oldEmailState, + keychainSharingSession.tokenOIDC != nil || keychainSharingSession.basicAuth != nil else { + return self.discard() + } + + JmapClient.shared.getNewEmails( + apiUrl: keychainSharingSession.apiUrl, + accountId: keychainSharingSession.accountId, + sinceState: oldEmailState, + authenticationType: keychainSharingSession.authenticationType, + tokenOidc: keychainSharingSession.tokenOIDC, + basicAuth: keychainSharingSession.basicAuth, + onSuccess: { emails in + self.keychainController.updateEmailStateToKeychain(accountId: keychainSharingSession.accountId, newState: newEmailState) + + self.modifiedContent?.subtitle = emails.first?.subject ?? "" + self.modifiedContent?.body = emails.first?.preview ?? "" + self.modifiedContent?.badge = NSNumber(value: emails.count) + return self.notify() + }, + onFailure: { error in + if let errorJmap = error as? JmapExceptions, errorJmap == JmapExceptions.notFoundNewEmails { + return self.discard() + } else { + self.modifiedContent?.body = "You have new emails" + self.modifiedContent?.badge = NSNumber(value: 1) + return self.notify() + } + } + ) + } + } + + private func notify() { + guard let modifiedContent else { + return discard() + } + + handler?(modifiedContent) + cleanUp() + } + + private func discard() { + handler?(UNMutableNotificationContent()) + cleanUp() + } + + private func cleanUp() { + handler = nil + modifiedContent = nil + } + + deinit { + cleanUp() + } +} diff --git a/ios/TwakeMailNSE/TwakeMailNSE.entitlements b/ios/TwakeMailNSE/TwakeMailNSE.entitlements new file mode 100644 index 000000000..cdaa20e23 --- /dev/null +++ b/ios/TwakeMailNSE/TwakeMailNSE.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.application-groups + + group.com.linagora.teammail + + keychain-access-groups + + $(AppIdentifierPrefix)com.linagora.ios.teammail.shared + + + diff --git a/ios/TwakeMailNSE/Utils/BundleExtension.swift b/ios/TwakeMailNSE/Utils/BundleExtension.swift new file mode 100644 index 000000000..fa44493a9 --- /dev/null +++ b/ios/TwakeMailNSE/Utils/BundleExtension.swift @@ -0,0 +1,16 @@ +import Foundation + +public extension Bundle { + /// The top-level bundle that contains the entire app. + static var app: Bundle { + var bundle = Bundle.main + if bundle.bundleURL.pathExtension == "appex" { + // Peel off two directory levels - MY_APP.app/PlugIns/MY_APP_EXTENSION.appex + let url = bundle.bundleURL.deletingLastPathComponent().deletingLastPathComponent() + if let otherBundle = Bundle(url: url) { + bundle = otherBundle + } + } + return bundle + } +} diff --git a/ios/TwakeMailNSE/Utils/InfoPlistReader.swift b/ios/TwakeMailNSE/Utils/InfoPlistReader.swift new file mode 100644 index 000000000..e54872480 --- /dev/null +++ b/ios/TwakeMailNSE/Utils/InfoPlistReader.swift @@ -0,0 +1,45 @@ +import Foundation + +struct InfoPlistReader { + private enum Keys { + static let baseBundleIdentifier = "baseBundleIdentifier" + static let keychainAccessGroupIdentifier = "keychainAccessGroupIdentifier" + static let bundleDisplayName = "CFBundleDisplayName" + } + + /// Info.plist reader on the bundle object that contains the current executable. + static let main = InfoPlistReader(bundle: .main) + + /// Info.plist reader on the bundle object that contains the main app executable. + static let app = InfoPlistReader(bundle: .app) + + private let bundle: Bundle + + /// Initializer + /// - Parameter bundle: bundle to read values from + init(bundle: Bundle) { + self.bundle = bundle + } + + /// Base bundle identifier set in Info.plist of the target + var baseBundleIdentifier: String { + infoPlistValue(forKey: Keys.baseBundleIdentifier) + } + + /// Keychain access group identifier set in Info.plist of the target + var keychainAccessGroupIdentifier: String { + infoPlistValue(forKey: Keys.keychainAccessGroupIdentifier) + } + + /// Bundle display name of the target + var bundleDisplayName: String { + infoPlistValue(forKey: Keys.bundleDisplayName) + } + + private func infoPlistValue(forKey key: String) -> T { + guard let result = bundle.object(forInfoDictionaryKey: key) as? T else { + fatalError("Add \(key) into your target's Info.plst") + } + return result + } +} diff --git a/ios/TwakeMailNSE/Utils/PayloadParser.swift b/ios/TwakeMailNSE/Utils/PayloadParser.swift new file mode 100644 index 000000000..7256020cd --- /dev/null +++ b/ios/TwakeMailNSE/Utils/PayloadParser.swift @@ -0,0 +1,37 @@ +import Foundation + +class PayloadParser { + static let shared: PayloadParser = PayloadParser() + + private let prefixState: String = ":" + + private func validatePushNotificationStateChange(state: String) -> Bool { + return state.contains(prefixState) && + (state.contains(TypeName.mailbox.rawValue) || + state.contains(TypeName.email.rawValue) || + state.contains(TypeName.EmailDelivery.rawValue)) + } + + func parsingPayloadNotification(payloadData: [String: Any]) -> [String: [TypeName: String]]{ + var mapStateChanges = [String: [TypeName: String]]() + + payloadData.keys.forEach { key in + if validatePushNotificationStateChange(state: key), + let accountId = key.components(separatedBy: prefixState).first, + let typeName = TypeName(rawValue: key.components(separatedBy: prefixState).last ?? ""), + let stateValue = payloadData[key] as? String { + if (mapStateChanges.keys.contains(accountId)) { + var mapTypes = mapStateChanges[accountId]! + mapTypes[typeName] = stateValue + mapStateChanges[accountId] = mapTypes + } else { + var mapTypes = [TypeName: String]() + mapTypes[typeName] = stateValue + mapStateChanges[accountId] = mapTypes + } + } + } + + return mapStateChanges + } +} diff --git a/model/lib/model.dart b/model/lib/model.dart index 40e7c379d..760cccb81 100644 --- a/model/lib/model.dart +++ b/model/lib/model.dart @@ -1,12 +1,12 @@ library model; -// Account -export 'account/personal_account.dart'; export 'account/account_request.dart'; export 'account/account_type.dart'; export 'account/authentication_type.dart'; -export 'account/password.dart'; export 'account/jmap_account.dart'; +export 'account/password.dart'; +// Account +export 'account/personal_account.dart'; // AutoComplete export 'autocomplete/auto_complete_pattern.dart'; // Contact @@ -25,55 +25,56 @@ export 'email/prefix_email_address.dart'; export 'email/presentation_email.dart'; export 'email/presentation_email_address.dart'; export 'email/read_actions.dart'; +export 'extensions/account_extension.dart'; +export 'extensions/account_id_extensions.dart'; export 'extensions/attachment_extension.dart'; // Extensions export 'extensions/email_address_extension.dart'; export 'extensions/email_body_part_extension.dart'; export 'extensions/email_extension.dart'; +export 'extensions/email_filter_condition_extension.dart'; +export 'extensions/email_id_extensions.dart'; export 'extensions/identity_extension.dart'; +export 'extensions/identity_id_extension.dart'; export 'extensions/keyword_identifier_extension.dart'; export 'extensions/list_attachment_extension.dart'; export 'extensions/list_email_address_extension.dart'; export 'extensions/list_email_content_extension.dart'; export 'extensions/list_email_extension.dart'; +export 'extensions/list_email_header_extension.dart'; export 'extensions/list_email_id_extension.dart'; export 'extensions/list_extension.dart'; +export 'extensions/list_identity_id_extension.dart'; export 'extensions/list_mailbox_extension.dart'; export 'extensions/list_presentation_email_extension.dart'; +export 'extensions/list_presentation_mailbox_extension.dart'; export 'extensions/mailbox_extension.dart'; export 'extensions/mailbox_id_extension.dart'; export 'extensions/mailbox_name_extension.dart'; export 'extensions/media_type_nullable_extension.dart'; +export 'extensions/personal_account_extension.dart'; export 'extensions/presentation_email_extension.dart'; export 'extensions/presentation_mailbox_extension.dart'; export 'extensions/properties_extension.dart'; export 'extensions/session_extension.dart'; export 'extensions/user_profile_extension.dart'; export 'extensions/utc_date_extension.dart'; -export 'extensions/email_filter_condition_extension.dart'; -export 'extensions/list_email_header_extension.dart'; -export 'extensions/personal_account_extension.dart'; -export 'extensions/list_presentation_mailbox_extension.dart'; -export 'extensions/list_identity_id_extension.dart'; -export 'extensions/email_id_extensions.dart'; -export 'extensions/account_id_extensions.dart'; -export 'extensions/account_extension.dart'; -export 'extensions/identity_id_extension.dart'; // Identity export 'identity/identity_request_dto.dart'; export 'mailbox/expand_mode.dart'; export 'mailbox/mailbox_property.dart'; +export 'mailbox/mailbox_state.dart'; // Mailbox export 'mailbox/presentation_mailbox.dart'; -export 'mailbox/mailbox_state.dart'; export 'mailbox/select_mode.dart'; +// Notification +export 'notification/notification_payload.dart'; export 'oidc/oidc_configuration.dart'; export 'oidc/request/oidc_request.dart'; -export 'oidc/response/oidc_link_dto.dart'; // OIDC export 'oidc/response/oidc_discovery_response.dart'; +export 'oidc/response/oidc_link_dto.dart'; export 'oidc/response/oidc_response.dart'; -export 'oidc/token.dart'; export 'oidc/token_id.dart'; export 'oidc/token_oidc.dart'; // Upload @@ -81,6 +82,4 @@ export 'upload/file_info.dart'; export 'upload/upload_response.dart'; // User export 'user/user_profile.dart'; -export 'user/user_profile_response.dart'; -// Notification -export 'notification/notification_payload.dart'; \ No newline at end of file +export 'user/user_profile_response.dart'; \ No newline at end of file