diff --git a/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs b/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs
index b899803..a7864c8 100644
--- a/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs
+++ b/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs
@@ -63,6 +63,11 @@ public class WindowsProvider : BaseProvider
///
public WebAccountProviderConfig WebAccountProviderConfig => _webAccountProviderConfig;
+ ///
+ /// Gets or sets which DispatcherQueue is used to dispatch UI updates.
+ ///
+ public DispatcherQueue DispatcherQueue { get; set; }
+
///
/// Gets a cache of important values for the signed in user.
///
@@ -71,7 +76,7 @@ public class WindowsProvider : BaseProvider
private readonly string[] _scopes;
private readonly AccountsSettingsPaneConfig? _accountsSettingsPaneConfig;
private readonly WebAccountProviderConfig _webAccountProviderConfig;
- private WebAccount _webAccount;
+ private WebAccount _webAccount = null;
///
/// Initializes a new instance of the class.
@@ -80,7 +85,8 @@ public class WindowsProvider : BaseProvider
/// Configuration values for the AccountsSettingsPane.
/// Configuration value for determining the available web account providers.
/// Determines whether the provider attempts to silently log in upon construction.
- public WindowsProvider(string[] scopes = null, WebAccountProviderConfig? webAccountProviderConfig = null, AccountsSettingsPaneConfig? accountsSettingsPaneConfig = null, bool autoSignIn = true)
+ /// The DispatcherQueue that should be used to dispatch UI updates, or null if this is being called from the UI thread.
+ public WindowsProvider(string[] scopes = null, WebAccountProviderConfig? webAccountProviderConfig = null, AccountsSettingsPaneConfig? accountsSettingsPaneConfig = null, bool autoSignIn = true, DispatcherQueue dispatcherQueue = null)
{
_scopes = scopes ?? DefaultScopes;
_webAccountProviderConfig = webAccountProviderConfig ?? new WebAccountProviderConfig()
@@ -89,7 +95,7 @@ public WindowsProvider(string[] scopes = null, WebAccountProviderConfig? webAcco
};
_accountsSettingsPaneConfig = accountsSettingsPaneConfig;
- _webAccount = null;
+ DispatcherQueue = dispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
State = ProviderState.SignedOut;
@@ -198,21 +204,7 @@ public override async Task GetTokenAsync(bool silentOnly = false)
}
// Attempt to authenticate interactively.
- var tcs = new TaskCompletionSource();
- var taskQueued = DispatcherQueue.GetForCurrentThread().TryEnqueue(async () =>
- {
- var result = await AuthenticateInteractiveAsync(_scopes);
- tcs.SetResult(result);
- });
-
- if (taskQueued)
- {
- authResult = await tcs.Task;
- }
- else
- {
- tcs.SetCanceled();
- }
+ authResult = await AuthenticateInteractiveAsync(_scopes);
}
if (authResult?.ResponseStatus == WebTokenRequestStatus.Success)
@@ -249,7 +241,7 @@ public override async Task GetTokenAsync(bool silentOnly = false)
/// Display AccountSettingsPane for the management of logged-in users.
///
/// .
- public async Task ShowAccountManagementPaneAsync()
+ public Task ShowAccountManagementPaneAsync()
{
if (_webAccount == null)
{
@@ -257,7 +249,7 @@ public async Task ShowAccountManagementPaneAsync()
}
var tcs = new TaskCompletionSource();
- _ = DispatcherQueue.GetForCurrentThread().TryEnqueue(async () =>
+ var taskQueued = DispatcherQueue.TryEnqueue(async () =>
{
AccountsSettingsPane pane = null;
try
@@ -284,7 +276,12 @@ public async Task ShowAccountManagementPaneAsync()
}
});
- await tcs.Task;
+ if (!taskQueued)
+ {
+ tcs.SetException(new InvalidOperationException("Failed to enqueue the operation."));
+ }
+
+ return tcs.Task;
}
///
@@ -392,34 +389,45 @@ private async Task AuthenticateSilentAsync(string[] scope
}
}
- private async Task AuthenticateInteractiveAsync(string[] scopes)
+ private Task AuthenticateInteractiveAsync(string[] scopes)
{
- try
+ var tcs = new TaskCompletionSource();
+ var taskQueued = DispatcherQueue.TryEnqueue(async () =>
{
- WebTokenRequestResult authResult = null;
-
- var account = _webAccount;
- if (account != null)
+ try
{
- // We already have the account.
- var webAccountProvider = account.WebAccountProvider;
- var webTokenRequest = GetWebTokenRequest(webAccountProvider, _webAccountProviderConfig.ClientId, scopes);
- authResult = await WebAuthenticationCoreManager.RequestTokenAsync(webTokenRequest, account);
+ WebTokenRequestResult authResult = null;
+
+ var account = _webAccount;
+ if (account != null)
+ {
+ // We already have the account.
+ var webAccountProvider = account.WebAccountProvider;
+ var webTokenRequest = GetWebTokenRequest(webAccountProvider, _webAccountProviderConfig.ClientId, scopes);
+ authResult = await WebAuthenticationCoreManager.RequestTokenAsync(webTokenRequest, account);
+ }
+ else
+ {
+ // We don't have an account. Prompt the user to provide one.
+ var webAccountProvider = await ShowAccountSettingsPaneAndGetProviderAsync();
+ var webTokenRequest = GetWebTokenRequest(webAccountProvider, _webAccountProviderConfig.ClientId, scopes);
+ authResult = await WebAuthenticationCoreManager.RequestTokenAsync(webTokenRequest);
+ }
+
+ tcs.SetResult(authResult);
}
- else
+ catch (Exception e)
{
- // We don't have an account. Prompt the user to provide one.
- var webAccountProvider = await ShowAccountSettingsPaneAndGetProviderAsync();
- var webTokenRequest = GetWebTokenRequest(webAccountProvider, _webAccountProviderConfig.ClientId, scopes);
- authResult = await WebAuthenticationCoreManager.RequestTokenAsync(webTokenRequest);
+ tcs.SetException(e);
}
+ });
- return authResult;
- }
- catch (HttpRequestException)
+ if (!taskQueued)
{
- throw; /* probably offline, no point continuing to interactive auth */
+ tcs.SetException(new InvalidOperationException("Failed to enqueue the operation."));
}
+
+ return tcs.Task;
}
///
diff --git a/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj b/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj
index 2104762..97f8bac 100644
--- a/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj
+++ b/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj
@@ -22,7 +22,7 @@
-
+
diff --git a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs b/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs
index 484d24f..97ffd48 100644
--- a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs
+++ b/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs
@@ -77,8 +77,7 @@ private async void GraphPresenter_Loaded(object sender, RoutedEventArgs e)
var request = new BaseRequest(
RequestBuilder.RequestUrl,
RequestBuilder.Client); // TODO: Do we need separate Options here?
- ////request.Method = HttpMethods.GET;
- request.Method = "GET";
+ request.Method = HttpMethods.GET;
request.QueryOptions = QueryOptions?.Select(option => (Microsoft.Graph.QueryOption)option)?.ToList() ?? new List();
// Handle Special QueryOptions
diff --git a/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj b/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj
index 8d501e3..0f03508 100644
--- a/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj
+++ b/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj
@@ -13,7 +13,7 @@
-
+
diff --git a/SampleTest/App.xaml.cs b/SampleTest/App.xaml.cs
index b12e662..1b89760 100644
--- a/SampleTest/App.xaml.cs
+++ b/SampleTest/App.xaml.cs
@@ -24,12 +24,8 @@ sealed partial class App : Application
public App()
{
this.InitializeComponent();
- this.Suspending += OnSuspending;
}
- // Which provider should be used for authentication?
- private readonly ProviderType _providerType = ProviderType.Mock;
-
// List of available authentication providers.
private enum ProviderType
{
@@ -38,42 +34,42 @@ private enum ProviderType
Windows
}
+ // Which provider should be used for authentication?
+ private readonly ProviderType _providerType = ProviderType.Mock;
+
///
/// Initialize the global authentication provider.
///
- private async void InitializeGlobalProvider()
+ private void InitializeGlobalProvider()
{
if (ProviderManager.Instance.GlobalProvider != null)
{
return;
}
- await Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
- {
- // Provider config
- string clientId = "YOUR_CLIENT_ID_HERE";
- string[] scopes = { "User.Read", "User.ReadBasic.All", "People.Read", "Calendars.Read", "Mail.Read", "Group.Read.All", "ChannelMessage.Read.All" };
- bool autoSignIn = true;
+ // Provider config
+ string clientId = "YOUR_CLIENT_ID_HERE";
+ string[] scopes = { "User.Read", "User.ReadBasic.All", "People.Read", "Calendars.Read", "Mail.Read", "Group.Read.All", "ChannelMessage.Read.All" };
+ bool autoSignIn = true;
- switch (_providerType)
- {
- // Mock provider
- case ProviderType.Mock:
- ProviderManager.Instance.GlobalProvider = new MockProvider(signedIn: autoSignIn);
- break;
-
- // Msal provider
- case ProviderType.Msal:
- ProviderManager.Instance.GlobalProvider = new MsalProvider(clientId: clientId, scopes: scopes, autoSignIn: autoSignIn);
- break;
-
- // Windows provider
- case ProviderType.Windows:
- var webAccountProviderConfig = new WebAccountProviderConfig(WebAccountProviderType.Msa, clientId);
- ProviderManager.Instance.GlobalProvider = new WindowsProvider(scopes, webAccountProviderConfig: webAccountProviderConfig, autoSignIn: autoSignIn);
- break;
- }
- });
+ switch (_providerType)
+ {
+ // Mock provider
+ case ProviderType.Mock:
+ ProviderManager.Instance.GlobalProvider = new MockProvider(signedIn: autoSignIn);
+ break;
+
+ // Msal provider
+ case ProviderType.Msal:
+ ProviderManager.Instance.GlobalProvider = new MsalProvider(clientId: clientId, scopes: scopes, autoSignIn: autoSignIn);
+ break;
+
+ // Windows provider
+ case ProviderType.Windows:
+ var webAccountProviderConfig = new WebAccountProviderConfig(WebAccountProviderType.Msa, clientId);
+ ProviderManager.Instance.GlobalProvider = new WindowsProvider(scopes, webAccountProviderConfig: webAccountProviderConfig, autoSignIn: autoSignIn);
+ break;
+ }
}
///
@@ -84,22 +80,9 @@ await Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
-
- // Do not repeat app initialization when the Window already has content,
- // just ensure that the window is active
if (rootFrame == null)
{
- // Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
-
- rootFrame.NavigationFailed += OnNavigationFailed;
-
- if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
- {
- //TODO: Load state from previously suspended application
- }
-
- // Place the frame in the current Window
Window.Current.Content = rootFrame;
}
@@ -107,40 +90,13 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
{
if (rootFrame.Content == null)
{
- // When the navigation stack isn't restored navigate to the first page,
- // configuring the new page by passing required information as a navigation
- // parameter
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
- // Ensure the current window is active
+
Window.Current.Activate();
InitializeGlobalProvider();
}
}
-
- ///
- /// Invoked when Navigation to a certain page fails
- ///
- /// The Frame which failed navigation
- /// Details about the navigation failure
- void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
- {
- throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
- }
-
- ///
- /// Invoked when application execution is being suspended. Application state is saved
- /// without knowing whether the application will be terminated or resumed with the contents
- /// of memory still intact.
- ///
- /// The source of the suspend request.
- /// Details about the suspend request.
- private void OnSuspending(object sender, SuspendingEventArgs e)
- {
- var deferral = e.SuspendingOperation.GetDeferral();
- //TODO: Save application state and stop any background activity
- deferral.Complete();
- }
}
}
diff --git a/SampleTest/SampleTest.csproj b/SampleTest/SampleTest.csproj
index 75520a4..64b2ca8 100644
--- a/SampleTest/SampleTest.csproj
+++ b/SampleTest/SampleTest.csproj
@@ -168,7 +168,7 @@
- 3.31.0
+ 4.0.0
6.2.12
diff --git a/Samples/ManualGraphRequestSample/App.xaml.cs b/Samples/ManualGraphRequestSample/App.xaml.cs
index 8c872a2..51fba54 100644
--- a/Samples/ManualGraphRequestSample/App.xaml.cs
+++ b/Samples/ManualGraphRequestSample/App.xaml.cs
@@ -31,6 +31,7 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
+
Window.Current.Activate();
}
}
diff --git a/Samples/UwpMsalProviderSample/App.xaml.cs b/Samples/UwpMsalProviderSample/App.xaml.cs
index 743e5a5..53c1340 100644
--- a/Samples/UwpMsalProviderSample/App.xaml.cs
+++ b/Samples/UwpMsalProviderSample/App.xaml.cs
@@ -22,15 +22,12 @@ public App()
///
void ConfigureGlobalProvider()
{
- DispatcherQueue.GetForCurrentThread().TryEnqueue(DispatcherQueuePriority.Normal, () =>
+ if (ProviderManager.Instance.GlobalProvider == null)
{
- if (ProviderManager.Instance.GlobalProvider == null)
- {
- string clientId = "YOUR-CLIENT-ID-HERE";
- string[] scopes = new string[] { "User.Read" };
- ProviderManager.Instance.GlobalProvider = new MsalProvider(clientId, scopes);
- }
- });
+ string clientId = "YOUR-CLIENT-ID-HERE";
+ string[] scopes = new string[] { "User.Read" };
+ ProviderManager.Instance.GlobalProvider = new MsalProvider(clientId, scopes);
+ }
}
protected override void OnLaunched(LaunchActivatedEventArgs e)
@@ -48,6 +45,7 @@ protected override void OnLaunched(LaunchActivatedEventArgs e)
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
+
Window.Current.Activate();
ConfigureGlobalProvider();
diff --git a/Samples/UwpWindowsProviderSample/App.xaml.cs b/Samples/UwpWindowsProviderSample/App.xaml.cs
index 4e2dcd0..fc2a9fc 100644
--- a/Samples/UwpWindowsProviderSample/App.xaml.cs
+++ b/Samples/UwpWindowsProviderSample/App.xaml.cs
@@ -29,15 +29,12 @@ public App()
///
void ConfigureGlobalProvider()
{
- DispatcherQueue.GetForCurrentThread().TryEnqueue(DispatcherQueuePriority.Normal, () =>
+ if (ProviderManager.Instance.GlobalProvider == null)
{
- if (ProviderManager.Instance.GlobalProvider == null)
- {
- string[] scopes = new string[] { "User.Read" };
- var paneConfig = GetAccountsSettingsPaneConfig();
- ProviderManager.Instance.GlobalProvider = new WindowsProvider(scopes, accountsSettingsPaneConfig: paneConfig);
- }
- });
+ string[] scopes = new string[] { "User.Read" };
+ var paneConfig = GetAccountsSettingsPaneConfig();
+ ProviderManager.Instance.GlobalProvider = new WindowsProvider(scopes, accountsSettingsPaneConfig: paneConfig);
+ }
}
AccountsSettingsPaneConfig GetAccountsSettingsPaneConfig()
diff --git a/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj b/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
index 9fde621..4547df5 100644
--- a/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
+++ b/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
@@ -160,7 +160,7 @@
5.10.3
- 1.25.1
+ 2.0.0
6.2.12