diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies
index 3762054..9236f3e 100644
--- a/example/.flutter-plugins-dependencies
+++ b/example/.flutter-plugins-dependencies
@@ -1 +1 @@
-{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"msal_flutter","path":"/Users/omar/Documents/GitHub/msal-flutter/","native_build":true,"dependencies":[]}],"android":[{"name":"msal_flutter","path":"/Users/omar/Documents/GitHub/msal-flutter/","native_build":true,"dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"msal_flutter","dependencies":[]}],"date_created":"2022-08-10 09:42:20.983087","version":"3.0.5"}
+{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"msal_flutter","path":"/Users/mahmoud/projects/50-msal-flutter/","native_build":true,"dependencies":[]}],"android":[{"name":"msal_flutter","path":"/Users/mahmoud/projects/50-msal-flutter/","native_build":true,"dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"msal_flutter","dependencies":[]}],"date_created":"2023-02-25 11:18:14.286829","version":"3.7.5"}
\ No newline at end of file
diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh
index 1203220..f55aaad 100755
--- a/example/ios/Flutter/flutter_export_environment.sh
+++ b/example/ios/Flutter/flutter_export_environment.sh
@@ -1,9 +1,9 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
-export "FLUTTER_ROOT=/Users/omar/Documents/flutter"
-export "FLUTTER_APPLICATION_PATH=/Users/omar/Documents/GitHub/msal-flutter/example"
+export "FLUTTER_ROOT=/Users/mahmoud/tools/flutter"
+export "FLUTTER_APPLICATION_PATH=/Users/mahmoud/projects/50-msal-flutter/example"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
-export "FLUTTER_TARGET=/Users/omar/Documents/GitHub/msal-flutter/example/lib/main.dart"
+export "FLUTTER_TARGET=/Users/mahmoud/projects/50-msal-flutter/example/lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=2.0.0.2"
export "FLUTTER_BUILD_NUMBER=2.0.0.2"
@@ -11,4 +11,4 @@ export "DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
-export "PACKAGE_CONFIG=.dart_tool/package_config.json"
+export "PACKAGE_CONFIG=/Users/mahmoud/projects/50-msal-flutter/example/.dart_tool/package_config.json"
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj
index 003b0bf..2c2fa09 100644
--- a/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/example/ios/Runner.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 50;
+ objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@@ -219,6 +219,7 @@
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist
index 2508686..604a353 100644
--- a/example/ios/Runner/Info.plist
+++ b/example/ios/Runner/Info.plist
@@ -60,5 +60,7 @@
CADisableMinimumFrameDurationOnPhone
+ UIApplicationSupportsIndirectInputEvents
+
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 168e8aa..4215d3f 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -15,7 +15,8 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State {
static const String _authority =
"https://msalfluttertest.b2clogin.com/tfp/3fab2993-1fec-4a8c-a6d8-2bfea01e64ea/B2C_1_phonesisu";
- static const String _iosRedirectUri = "msauth.com.muljin.msalflutterv2://auth";
+ static const String _iosRedirectUri =
+ "msauth.com.muljin.msalflutterv2://auth";
static const String _androidRedirectUri =
"msauth://uk.co.moodio.msal_flutter_example/TvkGQnk1ERb%2Bl9pB4OeyeWrYmqo%3D";
static const String _clientId = "fc6136e7-43d1-489c-b221-630e9e4402d3";
@@ -97,13 +98,12 @@ class _MyAppState extends State {
String res = 'res';
try {
- final response = await pca!.acquireTokenSilent(
- MSALSilentTokenParameters(
- scopes: _scopes,
- ),
- accounts?.isEmpty==true?null: accounts?.first);
- res = response?.account.identifier ?? '';
-
+ final response = await pca!.acquireTokenSilent(
+ MSALSilentTokenParameters(
+ scopes: _scopes,
+ ),
+ accounts?.isEmpty == true ? null : accounts?.first);
+ res = response?.account.identifier ?? '';
} on MsalUserCancelledException {
res = "User cancelled";
} on MsalNoAccountException {
@@ -137,8 +137,7 @@ class _MyAppState extends State {
String res;
try {
if (accounts?.isNotEmpty == true) {
- final resp =
- await pca!.logout(MSALSignoutParameters(), accounts!.first);
+ await pca!.logout(MSALSignoutParameters(), accounts!.first);
}
res = "Account removed";
} on MsalException {
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index 22df955..ba4ac15 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -4,7 +4,7 @@ version: 2.0.0-alpha.2
publish_to: 'none'
environment:
- sdk: ">=2.12.0 <3.0.0"
+ sdk: ">=2.17.0 <3.0.0"
dependencies:
flutter:
diff --git a/ios/Classes/MsalExtensions.swift b/ios/Classes/MsalExtensions.swift
index fe928c3..af50b50 100644
--- a/ios/Classes/MsalExtensions.swift
+++ b/ios/Classes/MsalExtensions.swift
@@ -5,8 +5,7 @@ import Foundation
import MSAL
extension MSALAccount {
-
-
+
var dictionary: [String: Any?] {
return ["username": username,
"identifier": identifier,
diff --git a/ios/Classes/SwiftMsalFlutterPluginV2.swift b/ios/Classes/SwiftMsalFlutterPluginV2.swift
index f671118..cc6eb8c 100644
--- a/ios/Classes/SwiftMsalFlutterPluginV2.swift
+++ b/ios/Classes/SwiftMsalFlutterPluginV2.swift
@@ -25,14 +25,13 @@ public class SwiftMsalFlutterPluginV2: NSObject, FlutterPlugin {
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch (call.method) {
-
- case "initialize": initialize(result: result, dict: call.arguments as! NSDictionary)
- case "initWebViewParams": initWebViewParams(result: result, dict: call.arguments as! NSDictionary)
- case "loadAccounts": loadAccounts( result: result, dict: call.arguments as? NSDictionary)
- case "acquireToken": acquireToken(result: result, dict: call.arguments as! NSDictionary)
- case "acquireTokenSilent": acquireTokenSilent(result: result, dict: call.arguments as! NSDictionary)
- case "logout": logout(result: result,dict: call.arguments as! NSDictionary)
- default: result(FlutterError(code: "INVALID_METHOD", message: "The method called is invalid", details: nil))
+ case "initialize": initialize(result: result, dict: call.arguments as! NSDictionary)
+ case "initWebViewParams": initWebViewParams(result: result, dict: call.arguments as! NSDictionary)
+ case "loadAccounts": loadAccounts( result: result, dict: call.arguments as? NSDictionary)
+ case "acquireToken": acquireToken(result: result, dict: call.arguments as! NSDictionary)
+ case "acquireTokenSilent": acquireTokenSilent(result: result, dict: call.arguments as! NSDictionary)
+ case "logout": logout(result: result,dict: call.arguments as! NSDictionary)
+ default: result(FlutterError(code: "INVALID_METHOD", message: "The method called is invalid", details: nil))
}
}
@@ -51,7 +50,6 @@ public class SwiftMsalFlutterPluginV2: NSObject, FlutterPlugin {
do {
let config: MSALPublicClientApplicationConfig = try MSALPublicClientApplicationConfig.fromDict(dictionary: dict)
let application = try MSALPublicClientApplication(configuration: config)
-// 'validateAuthority' is deprecated: Use knowAuthorities in MSALPublicClientApplicationConfig instead
applicationContext = application
result(true)
return
@@ -93,7 +91,7 @@ public class SwiftMsalFlutterPluginV2: NSObject, FlutterPlugin {
let parameters = MSALInteractiveTokenParameters.fromDict(dict: dict, param: webViewParameters)
applicationContext.acquireToken(with: parameters) { (token, error) in
if let error = error {
- result(FlutterError(code: "AUTH_ERROR", message: "Could not acquire token: \(error)", details: error.localizedDescription))
+ result(FlutterError(code: self.getErrorCode(error:error), message: "Could not acquire token: \(error)", details: error.localizedDescription))
return
}
guard let tokenResult: MSALResult = token else {
@@ -133,7 +131,7 @@ public class SwiftMsalFlutterPluginV2: NSObject, FlutterPlugin {
let silentParameters = MSALSilentTokenParameters.fromDict(dict: dict["tokenParameters"] as! NSDictionary, account: account)
self.applicationContext!.acquireTokenSilent(with: silentParameters, completionBlock: { (tokenResult, error) in
guard let authResult = tokenResult, error == nil else {
- result(FlutterError(code: "AUTH_ERROR", message: "Authentication error \(String(describing: error))", details: error?.localizedDescription))
+ result(FlutterError(code: self.getErrorCode(error:error), message: "Authentication error \(String(describing: error))", details: error?.localizedDescription))
return
}
result(authResult.toDict())
@@ -208,4 +206,37 @@ public class SwiftMsalFlutterPluginV2: NSObject, FlutterPlugin {
throw error
}
}
+
+ private func getErrorCode(error: Error?) -> String
+ {
+ guard let error = error as NSError? else { return "AUTH_ERROR"; }
+
+ if error.domain == MSALErrorDomain, let errorCode = MSALError(rawValue: error.code)
+ {
+ switch errorCode
+ {
+ case .interactionRequired:
+ return "INTERACTION_REQUIRED"
+ case .serverDeclinedScopes:
+ return "SERVER_DECLINED_SCOPES"
+ case .serverProtectionPoliciesRequired:
+ return "SERVER_PROTECTION_POLICIES_REQUIRED"
+ case .userCanceled:
+ return "CANCELLED"
+ case .internal:
+ return "INTERNAL_ERROR"
+ default:
+ return "AUTH_ERROR"
+ }
+ }
+
+ // Handle no internet connection.
+ if error.domain == NSURLErrorDomain && error.code == NSURLErrorNotConnectedToInternet
+ {
+ return "CONNECTION_ERROR"
+ }
+
+ return "AUTH_ERROR"
+
+ }
}
diff --git a/lib/src/exceptions/msal_exception.dart b/lib/src/exceptions/msal_exception.dart
index 8069580..a37779d 100644
--- a/lib/src/exceptions/msal_exception.dart
+++ b/lib/src/exceptions/msal_exception.dart
@@ -1,4 +1,5 @@
class MsalException implements Exception {
String errorMessage;
- MsalException(this.errorMessage);
+ String? errorDetails;
+ MsalException(this.errorMessage, {this.errorDetails});
}
diff --git a/lib/src/exceptions/msal_exceptions.dart b/lib/src/exceptions/msal_exceptions.dart
index 6699689..83cf45d 100644
--- a/lib/src/exceptions/msal_exceptions.dart
+++ b/lib/src/exceptions/msal_exceptions.dart
@@ -5,6 +5,7 @@ export 'msal_invalid_configuration_exception.dart';
export 'msal_invalid_scope_exception.dart';
export 'msal_no_account_exception.dart';
export 'msal_uninitialized_exception.dart';
-export 'msal_user_cancelled_exception.dart';
export 'msal_invalid_grant_exception.dart';
export 'msal_invalid_request_exception.dart';
+export 'msal_user_cancelled_exception.dart';
+export 'msal_user_interaction_required.dart';
diff --git a/lib/src/exceptions/msal_user_interaction_required.dart b/lib/src/exceptions/msal_user_interaction_required.dart
new file mode 100644
index 0000000..f7efa1c
--- /dev/null
+++ b/lib/src/exceptions/msal_user_interaction_required.dart
@@ -0,0 +1,5 @@
+import 'msal_exceptions.dart';
+
+class MsalUserInteractionRequired extends MsalException {
+ MsalUserInteractionRequired() : super("User interaction required to login.");
+}
diff --git a/lib/src/models/msal_android_config.dart b/lib/src/models/msal_android_config.dart
index bc8debd..c7decac 100644
--- a/lib/src/models/msal_android_config.dart
+++ b/lib/src/models/msal_android_config.dart
@@ -1,5 +1,3 @@
-import 'dart:io';
-
import 'package:msal_flutter/src/models/android_account_mode.dart';
import 'package:msal_flutter/src/models/android_logger_config.dart';
import 'package:msal_flutter/src/models/authorization_agent.dart';
diff --git a/lib/src/models/msal_public_client_application_config.dart b/lib/src/models/msal_public_client_application_config.dart
index f50748b..44a791b 100644
--- a/lib/src/models/msal_public_client_application_config.dart
+++ b/lib/src/models/msal_public_client_application_config.dart
@@ -1,4 +1,3 @@
-import 'dart:developer';
import 'dart:io';
import 'package:msal_flutter/src/models/authority.dart';
@@ -38,7 +37,7 @@ class MSALPublicClientApplicationConfig {
this.sliceConfig,
this.tokenExpirationBuffer,
this.androidConfig,
- }){
+ }) {
if (Platform.isAndroid) {
redirectUri = androidRedirectUri;
} else {
@@ -49,13 +48,12 @@ class MSALPublicClientApplicationConfig {
Map _toMapAndroid() {
return {
'client_id': clientId,
- 'redirect_uri' : redirectUri,
+ 'redirect_uri': redirectUri,
'client_capabilities': clientApplicationCapabilities,
...androidConfig?.toMap() ?? {},
}.cleanup();
}
-
Map _toMapIos() {
return {
'clientId': clientId,
@@ -69,9 +67,9 @@ class MSALPublicClientApplicationConfig {
'multipleCloudsSupported': multipleCloudsSupported,
'sliceConfig': sliceConfig?.toMap(),
'tokenExpirationBuffer': tokenExpirationBuffer,
-
}.cleanup();
}
+
Map toMap() {
if (Platform.isAndroid) {
return _toMapAndroid();
diff --git a/lib/src/models/msal_result.dart b/lib/src/models/msal_result.dart
index 8c6a6a0..1f9dc0b 100644
--- a/lib/src/models/msal_result.dart
+++ b/lib/src/models/msal_result.dart
@@ -1,5 +1,3 @@
-import 'dart:convert';
-
import 'package:msal_flutter/src/models/msal_account.dart';
import 'msal_tenant_profile.dart';
@@ -33,7 +31,8 @@ class MSALResult {
MSALResult.fromMap(Map map)
: this(
accessToken: map['accessToken'] ?? '',
- account: MSALAccount.fromMap(Map.from(map['account'])),
+ account:
+ MSALAccount.fromMap(Map.from(map['account'])),
authenticationScheme: map['authenticationScheme'] ?? '',
authority: Uri.parse(map['authority']),
authorizationHeader: map['authorizationHeader'] ?? '',
@@ -43,7 +42,10 @@ class MSALResult {
: null,
extendedLifeTimeToken: map['extendedLifeTimeToken'],
idToken: map['idToken'],
- scopes: List.from(map['scopes']??[]),
- tenantProfile:map['tenantProfile']==null?null: MSALTenantProfile.fromMap(Map.from(map['tenantProfile'])),
+ scopes: List.from(map['scopes'] ?? []),
+ tenantProfile: map['tenantProfile'] == null
+ ? null
+ : MSALTenantProfile.fromMap(
+ Map.from(map['tenantProfile'])),
);
}
diff --git a/lib/src/msal_public_client_application.dart b/lib/src/msal_public_client_application.dart
index be21587..3f2c99f 100644
--- a/lib/src/msal_public_client_application.dart
+++ b/lib/src/msal_public_client_application.dart
@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:flutter/services.dart';
+import 'package:msal_flutter/src/exceptions/msal_user_interaction_required.dart';
import '../msal_flutter.dart';
import 'exceptions/msal_scope_error_exception.dart';
@@ -109,6 +110,8 @@ class MSALPublicClientApplication {
return MsalNoAccountException();
case "NO_CLIENTID":
return MsalInvalidConfigurationException("Client Id not set");
+ case "INTERACTION_REQUIRED":
+ return MsalUserInteractionRequired();
case "INVALID_AUTHORITY":
return MsalInvalidConfigurationException("Invalid authroity set.");
case "INVALID_GRANT":
@@ -125,11 +128,12 @@ class MSALPublicClientApplication {
case "INIT_ERROR":
return MsalInitializationException();
case "SCOPE_ERROR":
+ case "SERVER_DECLINED_SCOPES":
return MsalScopeErrorException();
case "AUTH_ERROR":
case "UNKNOWN":
default:
- return MsalException("Authentication error");
+ return MsalException("Authentication error", errorDetails: e.message);
}
}
}
diff --git a/lib/src/utility/extensions/map_cleanup_extension.dart b/lib/src/utility/extensions/map_cleanup_extension.dart
index 49e24ca..4fcfa3d 100644
--- a/lib/src/utility/extensions/map_cleanup_extension.dart
+++ b/lib/src/utility/extensions/map_cleanup_extension.dart
@@ -2,9 +2,8 @@
extension MapCleanup on Map {
Map cleanup() {
removeWhere((key, value) {
- if (value is List ) {
- print(key);
- if(value.isEmpty) {
+ if (value is List) {
+ if (value.isEmpty) {
return true;
}
return false;
diff --git a/pubspec.yaml b/pubspec.yaml
index b54b5f6..1963793 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: msal_flutter
description: A Microsoft Authentication Library wrapper for Android and iOS
-version: 3.0.0-alpha1
+version: 3.0.0-beta1
homepage: https://github.com/muljin/msal-flutter
repository: https://github.com/muljin/msal-flutter
environment: