diff --git a/packages/amplify_datastore/android/src/main/kotlin/com/amazonaws/amplify/amplify_datastore/AmplifyDataStorePlugin.kt b/packages/amplify_datastore/android/src/main/kotlin/com/amazonaws/amplify/amplify_datastore/AmplifyDataStorePlugin.kt index 0ad51df167..c1c7ece49e 100644 --- a/packages/amplify_datastore/android/src/main/kotlin/com/amazonaws/amplify/amplify_datastore/AmplifyDataStorePlugin.kt +++ b/packages/amplify_datastore/android/src/main/kotlin/com/amazonaws/amplify/amplify_datastore/AmplifyDataStorePlugin.kt @@ -901,6 +901,7 @@ class AmplifyDataStorePlugin : override fun addApiPlugin( authProvidersList: List, + endpoints: Map, callback: (kotlin.Result) -> Unit ) { try { diff --git a/packages/amplify_datastore/android/src/main/kotlin/com/amazonaws/amplify/amplify_datastore/pigeons/NativePluginBindings.kt b/packages/amplify_datastore/android/src/main/kotlin/com/amazonaws/amplify/amplify_datastore/pigeons/NativePluginBindings.kt index 9dd0e1ee4e..71c7a0db1d 100644 --- a/packages/amplify_datastore/android/src/main/kotlin/com/amazonaws/amplify/amplify_datastore/pigeons/NativePluginBindings.kt +++ b/packages/amplify_datastore/android/src/main/kotlin/com/amazonaws/amplify/amplify_datastore/pigeons/NativePluginBindings.kt @@ -535,7 +535,7 @@ private object NativeApiBridgeCodec : StandardMessageCodec() { * Generated interface from Pigeon that represents a handler of messages from Flutter. */ interface NativeApiBridge { - fun addApiPlugin(authProvidersList: List, callback: (Result) -> Unit) + fun addApiPlugin(authProvidersList: List, endpoints: Map, callback: (Result) -> Unit) fun sendSubscriptionEvent(event: NativeGraphQLSubscriptionResponse, callback: (Result) -> Unit) companion object { @@ -552,7 +552,8 @@ interface NativeApiBridge { channel.setMessageHandler { message, reply -> val args = message as List val authProvidersListArg = args[0] as List - api.addApiPlugin(authProvidersListArg) { result: Result -> + val endpointsArg = args[1] as Map + api.addApiPlugin(authProvidersListArg, endpointsArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { reply.reply(wrapError(error)) diff --git a/packages/amplify_datastore/ios/Classes/FlutterApiPlugin.swift b/packages/amplify_datastore/ios/Classes/FlutterApiPlugin.swift index bd3fa4c122..4b82bc8051 100644 --- a/packages/amplify_datastore/ios/Classes/FlutterApiPlugin.swift +++ b/packages/amplify_datastore/ios/Classes/FlutterApiPlugin.swift @@ -2,22 +2,57 @@ import Foundation import Flutter import Combine -public class FlutterApiPlugin: APICategoryPlugin +public class FlutterApiPlugin: APICategoryPlugin, AWSAPIAuthInformation { public var key: PluginKey = "awsAPIPlugin" private let apiAuthFactory: APIAuthProviderFactory private let nativeApiPlugin: NativeApiPlugin private let nativeSubscriptionEvents: PassthroughSubject private var cancellables = AtomicDictionary() + private var endpoints: [String: String] init( apiAuthProviderFactory: APIAuthProviderFactory, nativeApiPlugin: NativeApiPlugin, - subscriptionEventBus: PassthroughSubject + subscriptionEventBus: PassthroughSubject, + endpoints: [String: String] ) { self.apiAuthFactory = apiAuthProviderFactory self.nativeApiPlugin = nativeApiPlugin self.nativeSubscriptionEvents = subscriptionEventBus + self.endpoints = endpoints + } + + public func defaultAuthType() throws -> AWSAuthorizationType { + try defaultAuthType(for: nil) + } + + public func defaultAuthType(for apiName: String?) throws -> AWSAuthorizationType { + if apiName == nil { + if self.endpoints.count == 1 { + return try stringToAWSAuthType(string: self.endpoints.first?.value) + } + return try stringToAWSAuthType(string: "") + } + let authType = self.endpoints[apiName!] + return try stringToAWSAuthType(string: authType) + } + + private func stringToAWSAuthType(string: String?) throws -> AWSAuthorizationType { + switch(string){ + case .some("apiKey"): + return AWSAuthorizationType.apiKey + case .some("none"): + return AWSAuthorizationType.none + case .some("iam"): + return AWSAuthorizationType.awsIAM + case .some("oidc"): + return AWSAuthorizationType.openIDConnect + case .some("userPools"): + return AWSAuthorizationType.amazonCognitoUserPools + default: + throw DataStoreError.configuration("No AWSAuthorizationType found from given string", "Please check API configuration") + } } public func query(request: GraphQLRequest) async throws -> GraphQLTask.Success where R : Decodable { diff --git a/packages/amplify_datastore/ios/Classes/SwiftAmplifyDataStorePlugin.swift b/packages/amplify_datastore/ios/Classes/SwiftAmplifyDataStorePlugin.swift index e94d41e0ed..681c679068 100644 --- a/packages/amplify_datastore/ios/Classes/SwiftAmplifyDataStorePlugin.swift +++ b/packages/amplify_datastore/ios/Classes/SwiftAmplifyDataStorePlugin.swift @@ -80,11 +80,12 @@ public class SwiftAmplifyDataStorePlugin: NSObject, FlutterPlugin, NativeAmplify } } - func addApiPlugin(authProvidersList: [String], completion: @escaping (Result) -> Void) { + func addApiPlugin(authProvidersList: [String], endpoints: [String: String], completion: @escaping (Result) -> Void) { do { let authProviders = authProvidersList.compactMap { AWSAuthorizationType(rawValue: $0) } + try Amplify.add( plugin: FlutterApiPlugin( apiAuthProviderFactory: FlutterAuthProviders( @@ -92,7 +93,8 @@ public class SwiftAmplifyDataStorePlugin: NSObject, FlutterPlugin, NativeAmplify nativeApiPlugin: nativeApiPlugin ), nativeApiPlugin: nativeApiPlugin, - subscriptionEventBus: nativeSubscriptionEventBus + subscriptionEventBus: nativeSubscriptionEventBus, + endpoints: endpoints ) ) return completion(.success(())) diff --git a/packages/amplify_datastore/ios/Classes/pigeons/NativePluginBindings.swift b/packages/amplify_datastore/ios/Classes/pigeons/NativePluginBindings.swift index a619cbb998..580f662bb9 100644 --- a/packages/amplify_datastore/ios/Classes/pigeons/NativePluginBindings.swift +++ b/packages/amplify_datastore/ios/Classes/pigeons/NativePluginBindings.swift @@ -556,7 +556,7 @@ class NativeApiBridgeCodec: FlutterStandardMessageCodec { /// /// Generated protocol from Pigeon that represents a handler of messages from Flutter. protocol NativeApiBridge { - func addApiPlugin(authProvidersList: [String], completion: @escaping (Result) -> Void) + func addApiPlugin(authProvidersList: [String], endpoints: [String: String], completion: @escaping (Result) -> Void) func sendSubscriptionEvent(event: NativeGraphQLSubscriptionResponse, completion: @escaping (Result) -> Void) } @@ -571,7 +571,8 @@ class NativeApiBridgeSetup { addApiPluginChannel.setMessageHandler { message, reply in let args = message as! [Any?] let authProvidersListArg = args[0] as! [String] - api.addApiPlugin(authProvidersList: authProvidersListArg) { result in + let endpointsArg = args[1] as! [String: String] + api.addApiPlugin(authProvidersList: authProvidersListArg, endpoints: endpointsArg) { result in switch result { case .success: reply(wrapResult(nil)) diff --git a/packages/amplify_datastore/ios/Classes/types/model/FlutterModelSchema.swift b/packages/amplify_datastore/ios/Classes/types/model/FlutterModelSchema.swift index a4f63621f7..ebd0f9eb73 100644 --- a/packages/amplify_datastore/ios/Classes/types/model/FlutterModelSchema.swift +++ b/packages/amplify_datastore/ios/Classes/types/model/FlutterModelSchema.swift @@ -97,12 +97,3 @@ struct FlutterModelSchema { return (fields, name) } } - -// TODO: Migrate to Async Swift v2 -// This enables custom selection set behavior within Amplify-Swift v1. -// Which allows models to be decoded when created on Android and received to iOS -//extension FlutterModelSchema: SubscriptionSelectionSetBehavior { -// public var includePrimaryKeysOnly: Bool { -// return true -// } -//} diff --git a/packages/amplify_datastore/ios/internal/Amplify/Categories/Logging/LogLevel.swift b/packages/amplify_datastore/ios/internal/Amplify/Categories/Logging/LogLevel.swift index cee8acfff4..aea36cdfbf 100644 --- a/packages/amplify_datastore/ios/internal/Amplify/Categories/Logging/LogLevel.swift +++ b/packages/amplify_datastore/ios/internal/Amplify/Categories/Logging/LogLevel.swift @@ -9,12 +9,12 @@ /// public extension Amplify { enum LogLevel: Int, Codable { + case none case error case warn case info case debug case verbose - case none public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() diff --git a/packages/amplify_datastore/ios/internal/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/Internal/OSLogWrapper.swift b/packages/amplify_datastore/ios/internal/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/Internal/OSLogWrapper.swift index ad3087d867..66529cc64d 100644 --- a/packages/amplify_datastore/ios/internal/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/Internal/OSLogWrapper.swift +++ b/packages/amplify_datastore/ios/internal/Amplify/DefaultPlugins/AWSUnifiedLoggingPlugin/Internal/OSLogWrapper.swift @@ -29,7 +29,7 @@ final class OSLogWrapper: Logger { } public func error(_ message: @autoclosure () -> String) { - guard enabled else { return } + guard enabled, logLevel.rawValue >= LogLevel.error.rawValue else { return } os_log("%@", log: osLog, type: OSLogType.error, @@ -37,7 +37,7 @@ final class OSLogWrapper: Logger { } public func error(error: Error) { - guard enabled else { return } + guard enabled, logLevel.rawValue >= LogLevel.error.rawValue else { return } os_log("%@", log: osLog, type: OSLogType.error, diff --git a/packages/amplify_datastore/lib/amplify_datastore.dart b/packages/amplify_datastore/lib/amplify_datastore.dart index fa58a61dca..685165c76a 100644 --- a/packages/amplify_datastore/lib/amplify_datastore.dart +++ b/packages/amplify_datastore/lib/amplify_datastore.dart @@ -106,6 +106,10 @@ class AmplifyDataStore extends DataStorePluginInterface if (apiPlugin != null && gqlConfig != null) { // ignore: invalid_use_of_protected_member final authProviders = apiPlugin.authProviders; + Map endpoints = {}; + config.api?.awsPlugin?.all.entries.forEach((e) { + endpoints[e.key] = e.value.authorizationType.name; + }); final nativePlugin = _NativeAmplifyApi(authProviders); NativeApiPlugin.setup(nativePlugin); @@ -113,7 +117,7 @@ class AmplifyDataStore extends DataStorePluginInterface try { final authProvidersList = authProviders.keys.map((key) => key.rawValue).toList(); - await nativeBridge.addApiPlugin(authProvidersList); + await nativeBridge.addApiPlugin(authProvidersList, endpoints); } on PlatformException catch (e) { if (e.code.contains('AmplifyAlreadyConfiguredException') || e.code.contains('AlreadyConfiguredException')) { diff --git a/packages/amplify_datastore/lib/src/native_plugin.g.dart b/packages/amplify_datastore/lib/src/native_plugin.g.dart index 327c28c658..d2ffdb76db 100644 --- a/packages/amplify_datastore/lib/src/native_plugin.g.dart +++ b/packages/amplify_datastore/lib/src/native_plugin.g.dart @@ -614,13 +614,15 @@ class NativeApiBridge { static const MessageCodec codec = _NativeApiBridgeCodec(); - Future addApiPlugin(List arg_authProvidersList) async { + Future addApiPlugin(List arg_authProvidersList, + Map arg_endpoints) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.amplify_datastore.NativeApiBridge.addApiPlugin', codec, binaryMessenger: _binaryMessenger); final List? replyList = - await channel.send([arg_authProvidersList]) as List?; + await channel.send([arg_authProvidersList, arg_endpoints]) + as List?; if (replyList == null) { throw PlatformException( code: 'channel-error', diff --git a/packages/amplify_datastore/pigeons/native_plugin.dart b/packages/amplify_datastore/pigeons/native_plugin.dart index d44a729c8f..d9c2b69043 100644 --- a/packages/amplify_datastore/pigeons/native_plugin.dart +++ b/packages/amplify_datastore/pigeons/native_plugin.dart @@ -63,7 +63,8 @@ abstract class NativeAuthBridge { @HostApi() abstract class NativeApiBridge { @async - void addApiPlugin(List authProvidersList); + void addApiPlugin( + List authProvidersList, Map endpoints); @async void sendSubscriptionEvent(NativeGraphQLSubscriptionResponse event);