From 67b47d216ec514ae19d0dd4b1c5e80934ae29281 Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Wed, 19 Apr 2023 16:41:05 +0200 Subject: [PATCH 1/9] FP-51: Use swift api for authenticateDevice and authenticateUserImplicitly --- .../Handlers/ResourcesHandler.swift | 19 ++++++++----------- .../OneginiModuleSwift+Auth.swift | 4 ++-- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift b/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift index 73a668c2..c9d4d251 100644 --- a/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift +++ b/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift @@ -5,7 +5,7 @@ typealias FlutterDataCallback = (Any?, SdkError?) -> Void protocol FetchResourcesHandlerProtocol: AnyObject { func authenticateDevice(_ scopes: [String]?, completion: @escaping (Result) -> Void) - func authenticateUserImplicitly(_ profile: ONGUserProfile, scopes: [String]?, completion: @escaping (Result) -> Void) + func authenticateUserImplicitly(_ profile: UserProfile, scopes: [String]?, completion: @escaping (Result) -> Void) func requestResource(_ type: ResourceRequestType, _ details: OWRequestDetails, completion: @escaping (Result) -> Void) } @@ -13,8 +13,7 @@ protocol FetchResourcesHandlerProtocol: AnyObject { class ResourcesHandler: FetchResourcesHandlerProtocol { func authenticateDevice(_ scopes: [String]?, completion: @escaping (Result) -> Void) { - Logger.log("authenticateDevice", sender: self) - ONGDeviceClient.sharedInstance().authenticateDevice(scopes) { _, error in + SharedDeviceClient.instance.authenticateDevice(with: scopes) { error in if let error = error { let mappedError = FlutterError(ErrorMapper().mapError(error)) completion(.failure(mappedError)) @@ -24,15 +23,13 @@ class ResourcesHandler: FetchResourcesHandlerProtocol { } } - func authenticateUserImplicitly(_ profile: ONGUserProfile, scopes: [String]?, completion: @escaping (Result) -> Void) { - Logger.log("authenticateImplicitly", sender: self) - ONGUserClient.sharedInstance().implicitlyAuthenticateUser(profile, scopes: scopes) { success, error in - if success { - completion(.success) - } else { - // This error construction is obviously not good, but it will work for now till we refactor this later - let mappedError = FlutterError(error.flatMap { ErrorMapper().mapError($0) } ?? SdkError(.genericError)) + func authenticateUserImplicitly(_ profile: UserProfile, scopes: [String]?, completion: @escaping (Result) -> Void) { + SharedUserClient.instance.implicitlyAuthenticate(user: profile, with: scopes) { error in + if let error = error { + let mappedError = FlutterError(ErrorMapper().mapError(error)) completion(.failure(mappedError)) + } else { + completion(.success) } } } diff --git a/ios/Classes/NativeBridge/ModuleExtensions/OneginiModuleSwift+Auth.swift b/ios/Classes/NativeBridge/ModuleExtensions/OneginiModuleSwift+Auth.swift index 37e52474..2c1b08bb 100644 --- a/ios/Classes/NativeBridge/ModuleExtensions/OneginiModuleSwift+Auth.swift +++ b/ios/Classes/NativeBridge/ModuleExtensions/OneginiModuleSwift+Auth.swift @@ -15,8 +15,8 @@ extension OneginiModuleSwift { public func authenticateUserImplicitly(_ profileId: String, _ scopes: [String]?, completion: @escaping (Result) -> Void) { - guard let profile = ONGClient.sharedInstance().userClient.userProfiles().first(where: { $0.profileId == profileId }) else { - completion(.failure(FlutterError(.noUserProfileIsAuthenticated))) + guard let profile = SharedUserClient.instance.userProfiles.first(where: { $0.profileId == profileId }) else { + completion(.failure(SdkError(.userProfileDoesNotExist).flutterError())) return } From 9b64037c37758b8789216cd1681b2eb5bf7f111d Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Thu, 20 Apr 2023 16:54:22 +0200 Subject: [PATCH 2/9] FP-51: Use Swift api for resourceRequests --- .../NativeBridge/Errors/SdkError.swift | 10 ++--- .../Handlers/ResourcesHandler.swift | 41 +++++++++---------- ios/Classes/SwiftOneginiPlugin.swift | 2 +- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/ios/Classes/NativeBridge/Errors/SdkError.swift b/ios/Classes/NativeBridge/Errors/SdkError.swift index 6066ddd7..afe9b96d 100644 --- a/ios/Classes/NativeBridge/Errors/SdkError.swift +++ b/ios/Classes/NativeBridge/Errors/SdkError.swift @@ -40,7 +40,7 @@ class SdkError: Error { } // Error codes with httResponse information - init(code: Int, errorDescription: String, response: ONGResourceResponse?, iosCode: Int? = nil, iosMessage: String? = nil) { + init(code: Int, errorDescription: String, response: ResourceResponse?, iosCode: Int? = nil, iosMessage: String? = nil) { self.code = code self.errorDescription = errorDescription @@ -48,7 +48,7 @@ class SdkError: Error { setResponseDetails(response, iosCode, iosMessage) } - init(_ wrapperError: OneWelcomeWrapperError, response: ONGResourceResponse?, iosCode: Int? = nil, iosMessage: String? = nil) { + init(_ wrapperError: OneWelcomeWrapperError, response: ResourceResponse?, iosCode: Int? = nil, iosMessage: String? = nil) { self.code = wrapperError.rawValue self.errorDescription = wrapperError.message() @@ -82,7 +82,7 @@ private extension SdkError { } } - func setResponseDetails(_ response: ONGResourceResponse?, _ iosCode: Int?, _ iosMessage: String?) { + func setResponseDetails(_ response: ResourceResponse?, _ iosCode: Int?, _ iosMessage: String?) { if response == nil { details["response"] = [String: Any?]() } else { @@ -100,11 +100,11 @@ private extension SdkError { } } -private extension ONGResourceResponse { +private extension ResourceResponse { func toJSON() -> [String: Any?] { return ["statusCode": statusCode, "headers": allHeaderFields, - "url": rawResponse.url?.absoluteString, + "url": response.url, "body": data != nil ? String(data: data!, encoding: .utf8) : nil ] } diff --git a/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift b/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift index c9d4d251..a4f10ee6 100644 --- a/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift +++ b/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift @@ -37,36 +37,35 @@ class ResourcesHandler: FetchResourcesHandlerProtocol { func requestResource(_ requestType: ResourceRequestType, _ details: OWRequestDetails, completion: @escaping (Result) -> Void) { Logger.log("requestResource", sender: self) - let request = generateONGResourceRequest(details) + let request = generateResourceRequest(details) let requestCompletion = getRequestCompletion(completion) switch requestType { case ResourceRequestType.implicit: // For consistency with Android we perform this step - if ONGUserClient.sharedInstance().implicitlyAuthenticatedUserProfile() == nil { + + if SharedUserClient.instance.implicitlyAuthenticatedUserProfile == nil { completion(.failure(FlutterError(SdkError(.unauthenticatedImplicitly)))) return } - - ONGUserClient.sharedInstance().fetchImplicitResource(request, completion: requestCompletion) + SharedUserClient.instance.sendImplicitRequest(request, completion: requestCompletion) case ResourceRequestType.anonymous: - ONGDeviceClient.sharedInstance().fetchResource(request, completion: requestCompletion) + SharedDeviceClient.instance.sendRequest(request, completion: requestCompletion) case ResourceRequestType.authenticated: - ONGUserClient.sharedInstance().fetchResource(request, completion: requestCompletion) + SharedUserClient.instance.sendAuthenticatedRequest(request, completion: requestCompletion) case ResourceRequestType.unauthenticated: - ONGDeviceClient.sharedInstance().fetchUnauthenticatedResource(request, completion: requestCompletion) + SharedDeviceClient.instance.sendUnauthenticatedRequest(request, completion: requestCompletion) } } } private extension ResourcesHandler { - func generateONGResourceRequest(_ details: OWRequestDetails) -> ONGResourceRequest { - Logger.log("generateONGResourceRequest", sender: self) - return ONGResourceRequest(path: details.path, - method: details.method.stringValue, - body: details.body?.data(using: .utf8), - headers: getRequestHeaders(details.headers) - ) + func generateResourceRequest(_ details: OWRequestDetails) -> ResourceRequest { + return ResourceRequestFactory.makeResourceRequest(path: details.path, + method: details.method.toHTTPMethod(), + body: details.body?.data(using: .utf8), + headers: getRequestHeaders(details.headers) + ) } func getRequestHeaders(_ headers: [String?: String?]?) -> [String: String]? { @@ -77,9 +76,9 @@ private extension ResourcesHandler { return headers.filter { $0.key != nil && $0.value != nil } as? [String: String] } - func getRequestCompletion(_ completion: @escaping (Result) -> Void) -> ((ONGResourceResponse?, Error?) -> Void)? { + func getRequestCompletion(_ completion: @escaping (Result) -> Void) -> ((ResourceResponse?, Error?) -> Void) { Logger.log("getCompletionRequest", sender: self) - let completionRequest: ((ONGResourceResponse?, Error?) -> Void)? = { response, error in + let completionRequest: ((ResourceResponse?, Error?) -> Void) = { response, error in if let error = error { if response != nil { let flutterError = FlutterError(SdkError(.errorCodeHttpRequest, response: response, iosCode: error.code, iosMessage: error.localizedDescription)) @@ -102,12 +101,12 @@ private extension ResourcesHandler { } private extension HttpRequestMethod { - var stringValue: String { + func toHTTPMethod() -> HTTPMethod { switch self { - case .get: return "GET" - case .post: return "POST" - case .delete: return "DELETE" - case .put: return "PUT" + case .get: return HTTPMethod.get + case .post: return HTTPMethod.post + case .delete: return HTTPMethod.delete + case .put: return HTTPMethod.put } } } diff --git a/ios/Classes/SwiftOneginiPlugin.swift b/ios/Classes/SwiftOneginiPlugin.swift index e4bc6df5..362c9069 100644 --- a/ios/Classes/SwiftOneginiPlugin.swift +++ b/ios/Classes/SwiftOneginiPlugin.swift @@ -43,7 +43,7 @@ extension OWIdentityProvider { } extension OWRequestResponse { - init(_ response: ONGResourceResponse) { + init(_ response: ResourceResponse) { headers = toOWRequestHeaders(response.allHeaderFields) body = String(data: response.data ?? Data(), encoding: .utf8) ?? "" status = Int64(response.statusCode) From 1cd77704e6c7dd0d66753a13d5c8ef838907f149 Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Thu, 20 Apr 2023 17:40:39 +0200 Subject: [PATCH 3/9] FP-51: Update how we get implicit details and make it nullsafe --- example/lib/screens/login_screen.dart | 156 ++++++++++---------------- 1 file changed, 62 insertions(+), 94 deletions(-) diff --git a/example/lib/screens/login_screen.dart b/example/lib/screens/login_screen.dart index 80afb071..c8d37bd7 100644 --- a/example/lib/screens/login_screen.dart +++ b/example/lib/screens/login_screen.dart @@ -1,4 +1,3 @@ -// @dart = 2.10 import 'dart:async'; import 'dart:convert'; @@ -21,9 +20,8 @@ class LoginScreen extends StatefulWidget { class _LoginScreenState extends State { bool isLoading = false; - OWBroadcastHelper broadcastHelper; - List> registrationSubscriptions; - List> authenticationSubscriptions; + List>? registrationSubscriptions; + List>? authenticationSubscriptions; @override initState() { @@ -94,7 +92,7 @@ class _LoginScreenState extends State { } } - authenticate(String profileId, OWAuthenticatorType authenticatorType) async { + authenticate(String profileId, OWAuthenticatorType? authenticatorType) async { try { var registrationResponse = await Onegini.instance.userClient .authenticateUser(profileId, authenticatorType); @@ -155,6 +153,19 @@ class _LoginScreenState extends State { } } + Widget _buildImplicitUserData(String profileId) { + return FutureBuilder( + future: getImplicitUserDetails(profileId), + builder: (context, snapshot) { + if (snapshot.hasData) { + return Text("${snapshot.data}"); + } else if (snapshot.hasError) { + return Text("Error getting implicit details."); + } + return CircularProgressIndicator(); + }); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -199,95 +210,51 @@ class _LoginScreenState extends State { FutureBuilder>( //userProfiles future: getUserProfiles(), - builder: (context, userProfiles) { - return (userProfiles.hasData && - userProfiles.data.length > 0) + builder: (context, snapshot) { + final userProfileData = snapshot.data; + return (userProfileData != null && + userProfileData.length > 0) ? Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - FutureBuilder( - //implicit - future: getImplicitUserDetails( - userProfiles.data.first?.profileId), - builder: - (context, implicitUserDetails) { - return implicitUserDetails.hasData - ? Column( - crossAxisAlignment: - CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - Text( - "──── Login ────", - style: TextStyle( - fontSize: 30), - textAlign: - TextAlign.center, - ), - Text( - implicitUserDetails - .data, - style: TextStyle( - fontSize: 20), - textAlign: - TextAlign.center, - ), - SizedBox( - height: 20, - ), - ElevatedButton( - onPressed: () { - authenticate( - userProfiles - .data - .first - ?.profileId, - null); - }, - child: Text( - 'Preferred authenticator'), - ), - Row( - mainAxisAlignment: - MainAxisAlignment - .center, - children: [ - ElevatedButton( - onPressed: () { - authenticate( - userProfiles - .data - .first - ?.profileId, - OWAuthenticatorType - .pin); - }, - child: Text('Pin'), - ), - SizedBox( - height: 10, - width: 10, - ), - ElevatedButton( - onPressed: () { - authenticate( - userProfiles - .data - .first - ?.profileId, - OWAuthenticatorType - .biometric); - }, - child: Text( - 'Biometrics'), - ), - ], - ), - ]) - : SizedBox.shrink(); - }) + Text( + "──── Login ────", + style: TextStyle(fontSize: 30), + textAlign: TextAlign.center, + ), + _buildImplicitUserData( + userProfileData.first.profileId), + ElevatedButton( + onPressed: () { + authenticate( + userProfileData.first.profileId, + null); + }, + child: Text('Preferred authenticator'), + ), + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + authenticate( + userProfileData.first.profileId, + OWAuthenticatorType.pin); + }, + child: Text('Pin'), + ), + ElevatedButton( + onPressed: () { + authenticate( + userProfileData.first.profileId, + OWAuthenticatorType.biometric); + }, + child: Text('Biometrics'), + ), + ], + ), ]) : SizedBox.shrink(); }), @@ -312,8 +279,9 @@ class _LoginScreenState extends State { ), FutureBuilder>( future: Onegini.instance.userClient.getIdentityProviders(), - builder: (BuildContext context, identityProviders) { - return identityProviders.hasData + builder: (BuildContext context, snapshot) { + final identityProviders = snapshot.data; + return identityProviders != null ? PopupMenuButton( child: Container( padding: EdgeInsets.all(20), @@ -330,9 +298,9 @@ class _LoginScreenState extends State { registrationWithIdentityProvider(value); }, itemBuilder: (context) { - return identityProviders.data + return identityProviders .map((e) => PopupMenuItem( - child: Text(e.name ?? ""), + child: Text(e.name), value: e.id, )) .toList(); From c1d8522a352b54df05860a988739a9be5fbf6388 Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Fri, 21 Apr 2023 10:00:50 +0200 Subject: [PATCH 4/9] FP-51: Move preferred authenticator into seperate build method --- example/lib/screens/user_screen.dart | 63 ++++++++++++++-------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/example/lib/screens/user_screen.dart b/example/lib/screens/user_screen.dart index 409ce1bd..d75e2a63 100644 --- a/example/lib/screens/user_screen.dart +++ b/example/lib/screens/user_screen.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:convert'; -import "package:collection/collection.dart"; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:onegini/events/onewelcome_events.dart'; @@ -151,7 +150,7 @@ class _UserScreenState extends State with RouteAware { }); } - Widget biometricAuthenticatorWidget() { + Widget _buildBiometricAuthenticatorWidget() { final authenticator = _biometricAuthenticator; if (authenticator != null) { return ListTile( @@ -177,32 +176,38 @@ class _UserScreenState extends State with RouteAware { return SizedBox.shrink(); } - Widget preferredAuthenticatorSelectorWidget() { + Widget _buildPreferredAuthenticatorSelectorWidget() { final biometricAuthenticator = _biometricAuthenticator; - return PopupMenuButton( - child: ListTile( - title: Text("set preferred authenticator"), - leading: Icon(Icons.add_to_home_screen), - ), - onSelected: (value) { - Onegini.instance.userClient - .setPreferredAuthenticator(value) - .whenComplete(() => getAuthenticators()); - }, - itemBuilder: (context) { - return [ - PopupMenuItem( - child: Text("Pin"), - value: OWAuthenticatorType.pin, - ), - if (biometricAuthenticator != null && - biometricAuthenticator.isRegistered) + return Column(mainAxisSize: MainAxisSize.min, children: [ + ListTile( + title: + Text("Preferred Authenticator: ${_preferredAuthenticator?.name} "), + ), + PopupMenuButton( + child: ListTile( + title: Text("set preferred authenticator"), + leading: Icon(Icons.add_to_home_screen), + ), + onSelected: (value) { + Onegini.instance.userClient + .setPreferredAuthenticator(value) + .whenComplete(() => getAuthenticators()); + }, + itemBuilder: (context) { + return [ PopupMenuItem( - child: Text(biometricAuthenticator.name), - value: OWAuthenticatorType.biometric, + child: Text("Pin"), + value: OWAuthenticatorType.pin, ), - ]; - }); + if (biometricAuthenticator != null && + biometricAuthenticator.isRegistered) + PopupMenuItem( + child: Text(biometricAuthenticator.name), + value: OWAuthenticatorType.biometric, + ), + ]; + }) + ]); } @override @@ -234,12 +239,8 @@ class _UserScreenState extends State with RouteAware { title: Text("Pin"), leading: Switch(value: true, onChanged: null), ), - biometricAuthenticatorWidget(), - ListTile( - title: Text( - "Preferred Authenticator: ${_preferredAuthenticator?.name} "), - ), - preferredAuthenticatorSelectorWidget(), + _buildBiometricAuthenticatorWidget(), + _buildPreferredAuthenticatorSelectorWidget(), Divider(), ListTile( title: Text("Change pin"), From 52883b6127e4fa7af5f016706bcb10ed384a144a Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Fri, 21 Apr 2023 10:38:05 +0200 Subject: [PATCH 5/9] FP-51: Refactor info screen --- example/lib/screens/user_screen.dart | 213 +++++++++++---------------- 1 file changed, 90 insertions(+), 123 deletions(-) diff --git a/example/lib/screens/user_screen.dart b/example/lib/screens/user_screen.dart index d75e2a63..56efb1d3 100644 --- a/example/lib/screens/user_screen.dart +++ b/example/lib/screens/user_screen.dart @@ -421,28 +421,102 @@ class Info extends StatefulWidget { } class _InfoState extends State { - Future getApplicationDetails() async { + Future _getApplicationDetails() async { await Onegini.instance.userClient .authenticateDevice(["read", "write", "application-details"]); - var response = await Onegini.instance.resourcesMethods.requestResource( + final response = await Onegini.instance.resourcesMethods.requestResource( ResourceRequestType.anonymous, RequestDetails( path: "application-details", method: HttpRequestMethod.get)); - var res = json.decode(response.body); - return applicationDetailsFromJson(res); + return applicationDetailsFromJson(response.body); } - Future getClientResource() async { - var response = await Onegini.instance.resourcesMethods + Future _getClientResource() async { + final response = await Onegini.instance.resourcesMethods .requestResourceAuthenticated( - RequestDetails(path: "devices", method: HttpRequestMethod.get)) - .catchError((error) { - print('Caught error: $error'); + RequestDetails(path: "devices", method: HttpRequestMethod.get)); + return clientResourceFromJson(response.body); + } - showFlutterToast(error.message); - }); + FutureBuilder _buildDeviceInfoList() { + return FutureBuilder( + future: _getClientResource(), + builder: (context, snapshot) { + final snapshotData = snapshot.data; + return snapshotData != null + ? ListView.builder( + itemCount: snapshotData.devices.length, + itemBuilder: (BuildContext context, int index) { + return ExpansionTile( + title: Text(snapshotData.devices[index].name), + expandedCrossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListTile( + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Id => ${snapshotData.devices[index].id}", + style: TextStyle(fontSize: 15), + ), + SizedBox(height: 10), + Text( + "Application => ${snapshotData.devices[index].application}", + style: TextStyle(fontSize: 15), + ), + SizedBox(height: 10), + Text( + "Mobile authentication enabled => ${snapshotData.devices[index].mobileAuthenticationEnabled.toString()}", + style: TextStyle(fontSize: 15), + ), + SizedBox(height: 10), + Text( + "Platform => ${snapshotData.devices[index].platform}", + style: TextStyle(fontSize: 15), + ), + SizedBox(), + ], + )) + ], + ); + }, + ) + : Center( + child: SizedBox( + child: CircularProgressIndicator(), + ), + ); + }, + ); + } - return clientResourceFromJson(response.body); + FutureBuilder _buildApplicationDetails() { + return FutureBuilder( + future: _getApplicationDetails(), + builder: (context, snapshot) { + return snapshot.hasData + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "application identifier => ${snapshot.data?.applicationIdentifier}", + style: TextStyle(fontSize: 15), + ), + SizedBox(height: 10), + Text( + "application platform => ${snapshot.data?.applicationPlatform}", + style: TextStyle(fontSize: 15), + ), + SizedBox(height: 10), + Text( + "application version => ${snapshot.data?.applicationVersion}", + style: TextStyle(fontSize: 15), + ), + ], + ) + : CircularProgressIndicator(); + }, + ); } @override @@ -453,118 +527,11 @@ class _InfoState extends State { margin: EdgeInsets.all(20), child: Column( children: [ - SizedBox( - height: 20, - ), - FutureBuilder( - future: getApplicationDetails(), - builder: (context, snapshot) { - return snapshot.hasData - ? Column( - children: [ - Row( - children: [ - Text( - "application identifier => ", - style: TextStyle(fontSize: 18), - ), - Text( - snapshot.data?.applicationIdentifier ?? "", - style: TextStyle(fontSize: 18), - ) - ], - ), - SizedBox( - height: 10, - ), - Row( - children: [ - Text( - "application platform => ", - style: TextStyle(fontSize: 18), - ), - Text( - snapshot.data?.applicationPlatform ?? "", - style: TextStyle(fontSize: 18), - ) - ], - ), - SizedBox( - height: 10, - ), - Row( - children: [ - Text( - "application version => ", - style: TextStyle(fontSize: 18), - ), - Text( - snapshot.data?.applicationVersion ?? "", - style: TextStyle(fontSize: 18), - ) - ], - ), - SizedBox( - height: 10, - ), - ], - ) - : Text(""); - }, - ), + SizedBox(height: 20), + _buildApplicationDetails(), + Divider(), Expanded( - child: FutureBuilder( - future: getClientResource(), - builder: (context, snapshot) { - final snapshotData = snapshot.data; - return snapshotData != null - ? ListView.builder( - itemCount: snapshotData.devices.length, - itemBuilder: (BuildContext context, int index) { - return ExpansionTile( - title: Text(snapshotData.devices[index].name), - expandedCrossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - "Id => ${snapshotData.devices[index].id}", - style: TextStyle(fontSize: 18), - ), - SizedBox( - height: 10, - ), - Text( - "Application => ${snapshotData.devices[index].application}", - style: TextStyle(fontSize: 18), - ), - SizedBox( - height: 10, - ), - Text( - "Mobile authentication enabled => ${snapshotData.devices[index].mobileAuthenticationEnabled.toString()}", - style: TextStyle(fontSize: 18), - ), - SizedBox( - height: 10, - ), - Text( - "Platform => ${snapshotData.devices[index].platform}", - style: TextStyle(fontSize: 18), - ), - SizedBox( - height: 10, - ), - ], - ); - }, - ) - : Center( - child: SizedBox( - child: CircularProgressIndicator(), - ), - ); - }, - ), + child: _buildDeviceInfoList(), ), ], ), From 15540544e296a5e62aa37eede9b856fe50c750bd Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Fri, 21 Apr 2023 10:51:22 +0200 Subject: [PATCH 6/9] FP-51: Make fingerprintscreen nullsafe --- example/lib/screens/fingerprint_screen.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/example/lib/screens/fingerprint_screen.dart b/example/lib/screens/fingerprint_screen.dart index 29b09ae7..ae1adb99 100644 --- a/example/lib/screens/fingerprint_screen.dart +++ b/example/lib/screens/fingerprint_screen.dart @@ -1,4 +1,3 @@ -// @dart = 2.10 import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:onegini/callbacks/onegini_fingerprint_callback.dart'; From 3c376cf412756dc8f53ba27c4fd25ee038be5e79 Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Fri, 21 Apr 2023 10:51:32 +0200 Subject: [PATCH 7/9] FP-51: Refactor method name --- example/lib/screens/user_screen.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/lib/screens/user_screen.dart b/example/lib/screens/user_screen.dart index 56efb1d3..c0ef9e27 100644 --- a/example/lib/screens/user_screen.dart +++ b/example/lib/screens/user_screen.dart @@ -176,7 +176,7 @@ class _UserScreenState extends State with RouteAware { return SizedBox.shrink(); } - Widget _buildPreferredAuthenticatorSelectorWidget() { + Widget _buildPreferredAuthenticatorWidget() { final biometricAuthenticator = _biometricAuthenticator; return Column(mainAxisSize: MainAxisSize.min, children: [ ListTile( @@ -240,7 +240,7 @@ class _UserScreenState extends State with RouteAware { leading: Switch(value: true, onChanged: null), ), _buildBiometricAuthenticatorWidget(), - _buildPreferredAuthenticatorSelectorWidget(), + _buildPreferredAuthenticatorWidget(), Divider(), ListTile( title: Text("Change pin"), From a6607c8c1f952ac294be3f97a14ef2922b83d86a Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Wed, 3 May 2023 11:29:29 +0200 Subject: [PATCH 8/9] FP-51: Re-add logging --- ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift b/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift index 58b2b9ab..88dbc61e 100644 --- a/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift +++ b/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift @@ -13,6 +13,7 @@ protocol FetchResourcesHandlerProtocol: AnyObject { class ResourcesHandler: FetchResourcesHandlerProtocol { func authenticateDevice(_ scopes: [String]?, completion: @escaping (Result) -> Void) { + Logger.log("authenticateDevice", sender: self) SharedDeviceClient.instance.authenticateDevice(with: scopes) { error in if let error = error { let mappedError = FlutterError(ErrorMapper().mapError(error)) @@ -24,6 +25,7 @@ class ResourcesHandler: FetchResourcesHandlerProtocol { } func authenticateUserImplicitly(_ profile: UserProfile, scopes: [String]?, completion: @escaping (Result) -> Void) { + Logger.log("authenticateUserImplicitly", sender: self) SharedUserClient.instance.implicitlyAuthenticate(user: profile, with: scopes) { error in if let error = error { let mappedError = FlutterError(ErrorMapper().mapError(error)) @@ -36,7 +38,6 @@ class ResourcesHandler: FetchResourcesHandlerProtocol { func requestResource(_ requestType: ResourceRequestType, _ details: OWRequestDetails, completion: @escaping (Result) -> Void) { Logger.log("requestResource", sender: self) - // Additional check for valid url let resourceUrl = ONGClient.sharedInstance().configModel.resourceBaseURL ?? "" if isValidUrl(details.path) == false && isValidUrl(resourceUrl + details.path) == false { From bb57dd6c7c50d80d6b2708dc7b6697d3658fd1a2 Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Wed, 3 May 2023 11:37:54 +0200 Subject: [PATCH 9/9] FP-51: Update Logger string to match new function name --- ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift b/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift index 88dbc61e..d45cfcd5 100644 --- a/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift +++ b/ios/Classes/NativeBridge/Handlers/ResourcesHandler.swift @@ -76,7 +76,7 @@ private extension ResourcesHandler { } func generateResourceRequest(_ details: OWRequestDetails) -> ResourceRequest { - Logger.log("generateONGResourceRequest", sender: self) + Logger.log("generateResourceRequest", sender: self) return ResourceRequestFactory.makeResourceRequest(path: details.path, method: details.method.toHTTPMethod(),