зеркало из https://github.com/microsoft/winsdkfb.git
Finish updating all sample apps to handle rerequest of permissions properly.
This commit is contained in:
Родитель
33b069ef95
Коммит
74e65c4616
|
@ -1,4 +1,5 @@
|
|||
.nuget
|
||||
*.csproj.user
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.suo
|
||||
|
|
|
@ -318,6 +318,7 @@ popd
|
|||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookMediaObject.h" />
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookMediaStream.h" />
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPaginatedArray.h" />
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPermissions.h" />
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePicture.h" />
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePictureControl.xaml.h">
|
||||
<DependentUpon>..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePictureControl.xaml</DependentUpon>
|
||||
|
@ -353,6 +354,7 @@ popd
|
|||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookMediaObject.cpp" />
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookMediaStream.cpp" />
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPaginatedArray.cpp" />
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPermissions.cpp" />
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePicture.cpp" />
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePictureControl.xaml.cpp">
|
||||
<DependentUpon>..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePictureControl.xaml</DependentUpon>
|
||||
|
|
|
@ -120,6 +120,9 @@
|
|||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\ScaleConverter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPermissions.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookAccessTokenData.h">
|
||||
|
@ -205,6 +208,9 @@
|
|||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\ScaleConverter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPermissions.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePictureControl.xaml" />
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookMediaObject.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookMediaStream.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookPaginatedArray.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookPermissions.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookProfilePicture.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookProfilePictureControl.xaml.h">
|
||||
<DependentUpon>$(MSBuildThisFileDirectory)FacebookProfilePictureControl.xaml</DependentUpon>
|
||||
|
@ -61,6 +62,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookMediaObject.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookMediaStream.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookPaginatedArray.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookPermissions.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBCursors.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBGroup.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBPage.cpp" />
|
||||
|
|
|
@ -81,6 +81,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)HlsColor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookPermissions.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)pch.cpp">
|
||||
|
@ -154,6 +157,9 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)HlsColor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookPermissions.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace Facebook
|
|||
*/
|
||||
public enum class ErrorSubcode : int
|
||||
{
|
||||
ErrorSubcodeAppNotAuthorized = 458,
|
||||
ErrorSubcodeSessionInvalidated = 466
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "pch.h"
|
||||
#include "FacebookLoginButton.h"
|
||||
#include "FacebookSession.h"
|
||||
#include "FacebookPermissions.h"
|
||||
|
||||
using namespace Concurrency;
|
||||
using namespace Facebook;
|
||||
|
@ -32,7 +33,6 @@ FBLoginButton::FBLoginButton() :
|
|||
{
|
||||
String^ styleKey = FBLoginButton::typeid->FullName;
|
||||
this->DefaultStyleKey = styleKey;
|
||||
m_permissions = ref new Vector<String^>();
|
||||
}
|
||||
|
||||
void FBLoginButton::OnApplyTemplate(
|
||||
|
@ -58,61 +58,21 @@ void FBLoginButton::OnApplyTemplate(
|
|||
//}
|
||||
//
|
||||
|
||||
IVector<String^>^ FBLoginButton::Permissions::get()
|
||||
FBPermissions^ FBLoginButton::Permissions::get()
|
||||
{
|
||||
return m_permissions;
|
||||
}
|
||||
|
||||
void FBLoginButton::Permissions::set(IVector<String^>^ Values)
|
||||
void FBLoginButton::Permissions::set(FBPermissions^ Permissions)
|
||||
{
|
||||
m_permissions->Clear();
|
||||
IIterator<String^>^ it = nullptr;
|
||||
for (it = Values->First(); it->HasCurrent; it->MoveNext())
|
||||
{
|
||||
String^ value = it->Current;
|
||||
m_permissions->Append(value);
|
||||
}
|
||||
m_permissions = Permissions;
|
||||
}
|
||||
|
||||
void FBLoginButton::InitWithPermissions(
|
||||
IVector<String^>^ permissions
|
||||
FBPermissions^ Permissions
|
||||
)
|
||||
{
|
||||
if (!m_permissions)
|
||||
{
|
||||
m_permissions = ref new Vector<String^>(0);
|
||||
}
|
||||
|
||||
m_permissions->Clear();
|
||||
|
||||
for (IIterator<String^>^ iter = permissions->First();
|
||||
iter->HasCurrent;
|
||||
iter->MoveNext())
|
||||
{
|
||||
m_permissions->Append(iter->Current);
|
||||
}
|
||||
}
|
||||
|
||||
String^ FBLoginButton::GetPermissions(
|
||||
)
|
||||
{
|
||||
String^ permissions = nullptr;
|
||||
if (m_permissions)
|
||||
{
|
||||
permissions = ref new String();
|
||||
|
||||
for (unsigned int i = 0; i < m_permissions->Size; i++)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
permissions += ",";
|
||||
}
|
||||
|
||||
permissions += m_permissions->GetAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
return permissions;
|
||||
m_permissions = Permissions;
|
||||
}
|
||||
|
||||
void FBLoginButton::OnClick(
|
||||
|
@ -128,14 +88,7 @@ void FBLoginButton::OnClick(
|
|||
}
|
||||
else
|
||||
{
|
||||
String^ permissions = GetPermissions();
|
||||
PropertySet^ parameters = ref new PropertySet();
|
||||
if (permissions != nullptr)
|
||||
{
|
||||
parameters->Insert(L"scope", permissions);
|
||||
}
|
||||
|
||||
create_task(s->LoginAsync(parameters))
|
||||
create_task(s->LoginAsync(m_permissions))
|
||||
.then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "FacebookSession.h"
|
||||
#include "FacebookPermissions.h"
|
||||
|
||||
namespace Facebook
|
||||
{
|
||||
|
@ -58,16 +59,16 @@ namespace Facebook
|
|||
//}
|
||||
|
||||
//! Publish permissions for user
|
||||
property Windows::Foundation::Collections::IVector<Platform::String^>^
|
||||
property Facebook::FBPermissions^
|
||||
Permissions
|
||||
{
|
||||
Windows::Foundation::Collections::IVector<Platform::String^>^ get();
|
||||
void set(Windows::Foundation::Collections::IVector<Platform::String^>^);
|
||||
Facebook::FBPermissions^ get();
|
||||
void set(Facebook::FBPermissions^);
|
||||
}
|
||||
|
||||
//! Ask for read permissions at login
|
||||
void InitWithPermissions(
|
||||
Windows::Foundation::Collections::IVector<Platform::String^>^ permissions
|
||||
Facebook::FBPermissions^ permissions
|
||||
);
|
||||
|
||||
event FBLoginErrorHandler^ FBLoginError;
|
||||
|
@ -85,6 +86,6 @@ namespace Facebook
|
|||
);
|
||||
|
||||
// SessionLoginBehavior m_loginBehavior;
|
||||
Platform::Collections::Vector<Platform::String^>^ m_permissions;
|
||||
Facebook::FBPermissions^ m_permissions;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#include <ppltasks.h>
|
||||
|
||||
#include "pch.h"
|
||||
#include "FacebookPermissions.h"
|
||||
|
||||
using namespace Facebook;
|
||||
using namespace Platform;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
|
||||
IVectorView<String^>^ FBPermissions::Values::get()
|
||||
{
|
||||
return _values;
|
||||
};
|
||||
|
||||
void FBPermissions::Values::set(
|
||||
IVectorView<String^>^ value
|
||||
)
|
||||
{
|
||||
_values = value;
|
||||
}
|
||||
|
||||
Platform::String^ FBPermissions::ToString(
|
||||
)
|
||||
{
|
||||
String^ permissions = nullptr;
|
||||
if (_values)
|
||||
{
|
||||
permissions = ref new String();
|
||||
|
||||
for (unsigned int i = 0; i < _values->Size; i++)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
permissions += ",";
|
||||
}
|
||||
|
||||
permissions += _values->GetAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
namespace Facebook
|
||||
{
|
||||
public ref class FBPermissions sealed
|
||||
{
|
||||
public:
|
||||
|
||||
property Windows::Foundation::Collections::IVectorView<Platform::String^>^ Values
|
||||
{
|
||||
Windows::Foundation::Collections::IVectorView<Platform::String^>^ get();
|
||||
void set(Windows::Foundation::Collections::IVectorView<Platform::String^>^ value);
|
||||
};
|
||||
|
||||
virtual Platform::String^ ToString(
|
||||
) override;
|
||||
|
||||
private:
|
||||
Windows::Foundation::Collections::IVectorView<Platform::String^>^ _values;
|
||||
};
|
||||
}
|
||||
|
|
@ -501,7 +501,7 @@ Windows::Foundation::IAsyncOperation<FBResult^>^ FBSession::ShowRequestsDialog(
|
|||
// the concurrency event object was deprecated in the Win10 SDK tools.
|
||||
// Switched to plane old Windows event, but that didn't work at all,
|
||||
// so polling for now.
|
||||
while (m_showingDialog && !dialogResponse);
|
||||
while (m_showingDialog && !dialogResponse)
|
||||
{
|
||||
dialogResponse = m_dialog->GetDialogResponse();
|
||||
Sleep(0);
|
||||
|
@ -674,9 +674,6 @@ String^ FBSession::GetRedirectUriString(
|
|||
)
|
||||
{
|
||||
Uri^ endURI = WebAuthenticationBroker::GetCurrentApplicationCallbackUri();
|
||||
String^ blerg = endURI->DisplayUri;
|
||||
OutputDebugString(blerg->Data());
|
||||
OutputDebugString(L"\n");
|
||||
return endURI->DisplayUri;
|
||||
}
|
||||
|
||||
|
@ -856,22 +853,33 @@ task<FBResult^> FBSession::RunWebViewLoginOnUIThread(
|
|||
}
|
||||
|
||||
IAsyncOperation<FBResult^>^ FBSession::LoginAsync(
|
||||
PropertySet^ Parameters
|
||||
FBPermissions^ Permissions
|
||||
)
|
||||
{
|
||||
m_dialog = ref new FacebookDialog();
|
||||
|
||||
return create_async([=]()
|
||||
{
|
||||
PropertySet^ parameters = ref new PropertySet();
|
||||
if (Permissions)
|
||||
{
|
||||
parameters->Insert(L"scope", Permissions->ToString());
|
||||
}
|
||||
|
||||
if (LoggedIn)
|
||||
{
|
||||
parameters->Insert(L"auth_type", L"rerequest");
|
||||
}
|
||||
|
||||
return create_task([=]() -> FBResult^
|
||||
{
|
||||
FBResult^ result = nullptr;
|
||||
|
||||
task<FBResult^> authTask = TryLoginViaWebView(Parameters);
|
||||
task<FBResult^> authTask = TryLoginViaWebView(parameters);
|
||||
result = authTask.get();
|
||||
if (!result)
|
||||
{
|
||||
authTask = TryLoginViaWebAuthBroker(Parameters);
|
||||
authTask = TryLoginViaWebAuthBroker(parameters);
|
||||
result = authTask.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "FacebookResult.h"
|
||||
#include "FBUser.h"
|
||||
#include "FacebookDialog.xaml.h"
|
||||
#include "FacebookPermissions.h"
|
||||
|
||||
namespace Facebook
|
||||
{
|
||||
|
@ -125,7 +126,7 @@ namespace Facebook
|
|||
);
|
||||
|
||||
Windows::Foundation::IAsyncOperation<FBResult^>^ LoginAsync(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
Facebook::FBPermissions^ Permissions
|
||||
);
|
||||
|
||||
private:
|
||||
|
|
|
@ -223,19 +223,5 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<<<<<<< HEAD
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\FBWinSDK.0.9.0\build\native\FBWinSDK.targets" Condition="Exists('..\packages\FBWinSDK.0.9.0\build\native\FBWinSDK.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\FBWinSDK.0.9.0\build\native\FBWinSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\FBWinSDK.0.9.0\build\native\FBWinSDK.props'))" />
|
||||
<Error Condition="!Exists('..\packages\FBWinSDK.0.9.0\build\native\FBWinSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\FBWinSDK.0.9.0\build\native\FBWinSDK.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\FBWinSDK-debug.0.9.0\build\FBWinSDK-debug.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\FBWinSDK-debug.0.9.0\build\FBWinSDK-debug.props'))" />
|
||||
</Target>
|
||||
=======
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
>>>>>>> 26_change_sample_sdk_references
|
||||
</Project>
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
|
||||
#include "pch.h"
|
||||
#include "MainPage.xaml.h"
|
||||
#include "UserInfo.xaml.h"
|
||||
#include "OptionsPage.xaml.h"
|
||||
|
||||
using namespace concurrency;
|
||||
using namespace Facebook;
|
||||
using namespace LoginCpp;
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
|
@ -85,20 +85,18 @@ void MainPage::SetSessionAppIds()
|
|||
s->WinAppId = winAppId;
|
||||
}
|
||||
|
||||
String^ MainPage::BuildPermissionsString(
|
||||
FBPermissions^ MainPage::BuildPermissions(
|
||||
)
|
||||
{
|
||||
String^ result = ref new String();
|
||||
FBPermissions^ result = ref new FBPermissions();
|
||||
Vector<String^>^ v = ref new Vector<String^>();
|
||||
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
result += L",";
|
||||
v->Append(ref new String(requested_permissions[i]));
|
||||
}
|
||||
|
||||
result += ref new String(requested_permissions[i]);
|
||||
}
|
||||
result->Values = v->GetView();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -134,20 +132,29 @@ BOOL MainPage::DidGetAllRequestedPermissions(
|
|||
return success;
|
||||
}
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
(!result->Succeeded) &&
|
||||
(result->ErrorInfo->Code == (int)Facebook::ErrorCode::ErrorCodeOauthException));
|
||||
}
|
||||
|
||||
BOOL MainPage::ShouldRerequest(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
result->Succeeded &&
|
||||
!DidGetAllRequestedPermissions());
|
||||
}
|
||||
|
||||
void MainPage::NavigateToOptionsPage()
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
|
||||
// We're redirecting to a page that shows simple user info, so
|
||||
// have to dispatch back to the UI thread.
|
||||
CoreWindow^ wind = CoreApplication::MainView->CoreWindow;
|
||||
|
||||
if (wind)
|
||||
{
|
||||
CoreDispatcher^ disp = wind->Dispatcher;
|
||||
if (disp)
|
||||
{
|
||||
disp->RunAsync(
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
|
@ -155,25 +162,65 @@ void MainPage::NavigateToOptionsPage()
|
|||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(OptionsPage::typeid);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task<FBResult^> MainPage::LoginViaRerequest(
|
||||
PropertySet^ Parameters
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
)
|
||||
{
|
||||
Parameters->Insert(L"auth_type", L"rerequest");
|
||||
return create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
// If we're logged out, the session has cleared the FB and Windows app IDs,
|
||||
// so they need to be set again. We load these IDs via the ResourceLoader
|
||||
// class, which must be accessed on the UI thread, which is why this call
|
||||
// is outside the task context.
|
||||
SetSessionAppIds();
|
||||
|
||||
return FBSession::ActiveSession->LoginAsync(Parameters);
|
||||
create_task(FBSession::ActiveSession->LoginAsync(BuildPermissions()))
|
||||
.then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
if (retry && (!DidGetAllRequestedPermissions()))
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(false);
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
void MainPage::LogoutAndRetry(
|
||||
)
|
||||
{
|
||||
// It's necessary to logout prior to reattempting login, because it could
|
||||
// be that the session has cached an access token that is no longer valid,
|
||||
// e.g. if the user revoked the app in Settings. FBSession::Logout clears
|
||||
// the session's cached access token, among other things.
|
||||
create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(TRUE);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::login_OnClicked(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e
|
||||
)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
|
@ -187,46 +234,30 @@ void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::Rout
|
|||
}
|
||||
else
|
||||
{
|
||||
PropertySet^ parameters = ref new PropertySet();
|
||||
|
||||
parameters->Insert(L"scope", BuildPermissionsString());
|
||||
|
||||
create_task(sess->LoginAsync(parameters)).then([=](FBResult^ result)
|
||||
create_task(sess->LoginAsync(BuildPermissions())).then([=](FBResult^ result)
|
||||
{
|
||||
task<FBResult^> nextResult = create_task([=]()
|
||||
// There may be other cases where an a failed login request should
|
||||
// prompt the app to retry login, but this one is common enough that
|
||||
// it's helpful to demonstrate handling it here. If the predicate
|
||||
// returns TRUE, the user has gone to facebook.com in the browser,
|
||||
// and removed our app from their list off allowed apps in Settings.
|
||||
if (WasAppPermissionRemovedByUser(result))
|
||||
{
|
||||
return result;
|
||||
});
|
||||
|
||||
if ((!result->Succeeded) &&
|
||||
((result->ErrorInfo->Code == 190) && (result->ErrorInfo->Subcode == 466)))
|
||||
{
|
||||
nextResult = LoginViaRerequest(parameters);
|
||||
LogoutAndRetry();
|
||||
}
|
||||
|
||||
return nextResult;
|
||||
})
|
||||
.then([=](FBResult^ loginResult)
|
||||
else if (ShouldRerequest(result))
|
||||
{
|
||||
task<FBResult^> finalResult = create_task([=]()
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
return loginResult;
|
||||
});
|
||||
|
||||
if (loginResult->Succeeded)
|
||||
{
|
||||
if (!DidGetAllRequestedPermissions())
|
||||
{
|
||||
finalResult = LoginViaRerequest(parameters);
|
||||
TryRerequest(FALSE);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
})
|
||||
.then([=](FBResult^ finalResult)
|
||||
{
|
||||
if (finalResult->Succeeded)
|
||||
else if (result->Succeeded)
|
||||
{
|
||||
// Got a token and all our permissions.
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -37,17 +37,28 @@ namespace LoginCpp
|
|||
void MainPage::SetSessionAppIds(
|
||||
);
|
||||
|
||||
Platform::String^ BuildPermissionsString(
|
||||
Facebook::FBPermissions^ BuildPermissions(
|
||||
);
|
||||
|
||||
BOOL DidGetAllRequestedPermissions(
|
||||
);
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
BOOL ShouldRerequest(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
void NavigateToOptionsPage(
|
||||
);
|
||||
|
||||
concurrency::task<Facebook::FBResult^> MainPage::LoginViaRerequest(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
);
|
||||
|
||||
void MainPage::LogoutAndRetry(
|
||||
);
|
||||
|
||||
void login_OnClicked(
|
||||
|
|
|
@ -23,27 +23,28 @@
|
|||
#include "MainPage.xaml.h"
|
||||
#include "OptionsPage.xaml.h"
|
||||
|
||||
using namespace LoginCpp;
|
||||
|
||||
using namespace concurrency;
|
||||
using namespace Facebook;
|
||||
using namespace LoginCpp;
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::ApplicationModel::Resources;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::Security::Authentication::Web;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
using namespace Windows::UI::Xaml::Controls::Primitives;
|
||||
using namespace Windows::UI::Xaml::Data;
|
||||
using namespace Windows::UI::Xaml::Input;
|
||||
using namespace Windows::UI::Xaml::Media;
|
||||
using namespace Windows::UI::Xaml::Navigation;
|
||||
using namespace Facebook;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
|
||||
|
||||
#define FBAppIDName L"FBApplicationId"
|
||||
#define FBStoreAppIDName L"FBWindowsAppId"
|
||||
|
@ -61,6 +62,10 @@ const wchar_t* requested_permissions[] =
|
|||
MainPage::MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
String^ whatever = WebAuthenticationBroker::GetCurrentApplicationCallbackUri()->DisplayUri + L"\n";
|
||||
OutputDebugString(whatever->Data());
|
||||
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
|
@ -80,20 +85,18 @@ void MainPage::SetSessionAppIds()
|
|||
s->WinAppId = winAppId;
|
||||
}
|
||||
|
||||
String^ MainPage::BuildPermissionsString(
|
||||
FBPermissions^ MainPage::BuildPermissions(
|
||||
)
|
||||
{
|
||||
String^ result = ref new String();
|
||||
FBPermissions^ result = ref new FBPermissions();
|
||||
Vector<String^>^ v = ref new Vector<String^>();
|
||||
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
result += L",";
|
||||
v->Append(ref new String(requested_permissions[i]));
|
||||
}
|
||||
|
||||
result += ref new String(requested_permissions[i]);
|
||||
}
|
||||
result->Values = v->GetView();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -129,20 +132,30 @@ BOOL MainPage::DidGetAllRequestedPermissions(
|
|||
return success;
|
||||
}
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
(!result->Succeeded) &&
|
||||
((result->ErrorInfo->Code == (int)Facebook::ErrorCode::ErrorCodeOauthException) &&
|
||||
(result->ErrorInfo->Subcode == (int)Facebook::ErrorSubcode::ErrorSubcodeSessionInvalidated)));
|
||||
}
|
||||
|
||||
BOOL MainPage::ShouldRerequest(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
result->Succeeded &&
|
||||
!DidGetAllRequestedPermissions());
|
||||
}
|
||||
|
||||
void MainPage::NavigateToOptionsPage()
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
|
||||
// We're redirecting to a page that shows simple user info, so
|
||||
// have to dispatch back to the UI thread.
|
||||
CoreWindow^ wind = CoreApplication::MainView->CoreWindow;
|
||||
|
||||
if (wind)
|
||||
{
|
||||
CoreDispatcher^ disp = wind->Dispatcher;
|
||||
if (disp)
|
||||
{
|
||||
disp->RunAsync(
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
|
@ -150,21 +163,58 @@ void MainPage::NavigateToOptionsPage()
|
|||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(OptionsPage::typeid);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task<FBResult^> MainPage::LoginViaRerequest(
|
||||
PropertySet^ Parameters
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
)
|
||||
{
|
||||
Parameters->Insert(L"auth_type", L"rerequest");
|
||||
return create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
// If we're logged out, the session has cleared the FB and Windows app IDs,
|
||||
// so they need to be set again. We load these IDs via the ResourceLoader
|
||||
// class, which must be accessed on the UI thread, which is why this call
|
||||
// is outside the task context.
|
||||
SetSessionAppIds();
|
||||
|
||||
return FBSession::ActiveSession->LoginAsync(Parameters);
|
||||
create_task(FBSession::ActiveSession->LoginAsync(BuildPermissions()))
|
||||
.then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
if (retry && (!DidGetAllRequestedPermissions()))
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(false);
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::LogoutAndRetry(
|
||||
)
|
||||
{
|
||||
// It's necessary to logout prior to reattempting login, because it could
|
||||
// be that the session has cached an access token that is no longer valid,
|
||||
// e.g. if the user revoked the app in Settings. FBSession::Logout clears
|
||||
// the session's cached access token, among other things.
|
||||
create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(TRUE);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -182,49 +232,32 @@ void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::Rout
|
|||
}
|
||||
else
|
||||
{
|
||||
PropertySet^ parameters = ref new PropertySet();
|
||||
|
||||
parameters->Insert(L"scope", BuildPermissionsString());
|
||||
|
||||
create_task(sess->LoginAsync(parameters)).then([=](FBResult^ result)
|
||||
create_task(sess->LoginAsync(BuildPermissions())).then([=](FBResult^ result)
|
||||
{
|
||||
task<FBResult^> nextResult = create_task([=]()
|
||||
// There may be other cases where an a failed login request should
|
||||
// prompt the app to retry login, but this one is common enough that
|
||||
// it's helpful to demonstrate handling it here. If the predicate
|
||||
// returns TRUE, the user has gone to facebook.com in the browser,
|
||||
// and removed our app from their list off allowed apps in Settings.
|
||||
if (WasAppPermissionRemovedByUser(result))
|
||||
{
|
||||
return result;
|
||||
});
|
||||
|
||||
if ((!result->Succeeded) &&
|
||||
((result->ErrorInfo->Code == 190) && (result->ErrorInfo->Subcode == 466)))
|
||||
{
|
||||
nextResult = LoginViaRerequest(parameters);
|
||||
LogoutAndRetry();
|
||||
}
|
||||
|
||||
return nextResult;
|
||||
})
|
||||
.then([=](FBResult^ loginResult)
|
||||
else if (ShouldRerequest(result))
|
||||
{
|
||||
task<FBResult^> finalResult = create_task([=]()
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
return loginResult;
|
||||
});
|
||||
|
||||
if (loginResult->Succeeded)
|
||||
{
|
||||
if (!DidGetAllRequestedPermissions())
|
||||
{
|
||||
finalResult = LoginViaRerequest(parameters);
|
||||
TryRerequest(FALSE);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
})
|
||||
.then([=](FBResult^ finalResult)
|
||||
{
|
||||
if (finalResult->Succeeded)
|
||||
else if (result && result->Succeeded)
|
||||
{
|
||||
// Got a token, and all the permissions we wanted - go ahead to the options page
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,19 +37,32 @@ namespace LoginCpp
|
|||
void MainPage::SetSessionAppIds(
|
||||
);
|
||||
|
||||
Platform::String^ BuildPermissionsString(
|
||||
Facebook::FBPermissions^ BuildPermissions(
|
||||
);
|
||||
|
||||
BOOL DidGetAllRequestedPermissions(
|
||||
);
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
BOOL ShouldRerequest(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
void NavigateToOptionsPage(
|
||||
);
|
||||
|
||||
concurrency::task<Facebook::FBResult^> MainPage::LoginViaRerequest(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
);
|
||||
|
||||
void login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
void MainPage::LogoutAndRetry(
|
||||
);
|
||||
|
||||
void login_OnClicked(
|
||||
Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<DebuggerFlavor>WindowsPhoneEmulatorDebugger</DebuggerFlavor>
|
||||
<WindowsPhoneEmulatorID>8BDF218D-FDBB-4A97-90F9-3AA33B559A92;Mobile Emulator 10.0.10240.0 WVGA 4 inch 512MB</WindowsPhoneEmulatorID>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -9,7 +9,7 @@
|
|||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Grid>
|
||||
<Button x:Name ="LoginButton" Content="Login" HorizontalAlignment="Left" Margin="39,48,0,0" VerticalAlignment="Top" Click="LoginButton_Click" Width="315"/>
|
||||
<Button x:Name ="LoginButton" Content="Login" HorizontalAlignment="Left" Margin="39,48,0,0" VerticalAlignment="Top" Click="login_OnClicked" Width="315"/>
|
||||
<TextBlock FontSize="14" HorizontalAlignment="Left" Margin="39,302,0,0" TextWrapping="Wrap" Text="Access Token:" VerticalAlignment="Top" Width="261" Height="18"/>
|
||||
<TextBlock x:Name="ResponseText" FontSize="14" HorizontalAlignment="Left" Margin="39,325,0,0" Text="TextBox" TextWrapping="Wrap" VerticalAlignment="Top" Height="94" Width="261"/>
|
||||
<TextBlock FontSize="14" HorizontalAlignment="Left" Margin="39,445,0,0" TextWrapping="Wrap" Text="Expires" VerticalAlignment="Top" Height="24" Width="261"/>
|
||||
|
|
|
@ -23,13 +23,18 @@
|
|||
#include "MainPage.xaml.h"
|
||||
#include "OptionsPage.xaml.h"
|
||||
|
||||
using namespace LoginCpp;
|
||||
|
||||
using namespace concurrency;
|
||||
using namespace Facebook;
|
||||
using namespace LoginCpp;
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::ApplicationModel::Resources;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Security::Authentication::Web;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
|
@ -38,14 +43,11 @@ using namespace Windows::UI::Xaml::Data;
|
|||
using namespace Windows::UI::Xaml::Input;
|
||||
using namespace Windows::UI::Xaml::Media;
|
||||
using namespace Windows::UI::Xaml::Navigation;
|
||||
using namespace Windows::ApplicationModel::Resources;
|
||||
using namespace Windows::Globalization;
|
||||
using namespace Facebook;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
|
||||
|
||||
#define FBAppIDName L"FBApplicationId"
|
||||
#define FBPhoneAppIDName L"FBWinPhoneAppId"
|
||||
#define FBStoreAppIDName L"FBWindowsAppId"
|
||||
#define PermissionGranted L"granted"
|
||||
|
||||
const wchar_t* requested_permissions[] =
|
||||
|
@ -57,46 +59,16 @@ const wchar_t* requested_permissions[] =
|
|||
L"user_location"
|
||||
};
|
||||
|
||||
|
||||
MainPage::MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
String^ whatever = WebAuthenticationBroker::GetCurrentApplicationCallbackUri()->DisplayUri + L"\n";
|
||||
OutputDebugString(whatever->Data());
|
||||
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when this page is about to be displayed in a Frame.
|
||||
/// </summary>
|
||||
/// <param name="e">Event data that describes how this page was reached. The Parameter
|
||||
/// property is typically used to configure the page.</param>
|
||||
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
|
||||
{
|
||||
(void)e; // Unused parameter
|
||||
|
||||
// TODO: Prepare page for display here.
|
||||
|
||||
// TODO: If your application contains multiple pages, ensure that you are
|
||||
// handling the hardware Back button by registering for the
|
||||
// Windows::Phone::UI::Input::HardwareButtons.BackPressed event.
|
||||
// If you are using the NavigationHelper provided by some templates,
|
||||
// this event is handled for you.
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
if (sess->LoggedIn)
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
Calendar^ cal = ref new Calendar();
|
||||
cal->SetDateTime(sess->AccessTokenData->ExpirationDate);
|
||||
|
||||
ResponseText->Text = sess->AccessTokenData->AccessToken;
|
||||
|
||||
ExpirationDate->Text = cal->DayOfWeekAsString() + "," + cal->YearAsString() + "/" +
|
||||
cal->MonthAsNumericString() + "/" + cal->DayAsString() + ", " +
|
||||
cal->HourAsPaddedString(2) + ":" + cal->MinuteAsPaddedString(2) + ":" +
|
||||
cal->SecondAsPaddedString(2);
|
||||
}
|
||||
}
|
||||
|
||||
void MainPage::SetSessionAppIds()
|
||||
{
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
|
@ -106,27 +78,25 @@ void MainPage::SetSessionAppIds()
|
|||
ResourceLoader^ rl = ResourceLoader::GetForCurrentView();
|
||||
|
||||
String^ appId = rl->GetString(FBAppIDName);
|
||||
String^ winAppId = rl->GetString(FBPhoneAppIDName);
|
||||
String^ winAppId = rl->GetString(FBStoreAppIDName);
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s->FBAppId = appId;
|
||||
s->WinAppId = winAppId;
|
||||
}
|
||||
|
||||
String^ MainPage::BuildPermissionsString(
|
||||
FBPermissions^ MainPage::BuildPermissions(
|
||||
)
|
||||
{
|
||||
String^ result = ref new String();
|
||||
FBPermissions^ result = ref new FBPermissions();
|
||||
Vector<String^>^ v = ref new Vector<String^>();
|
||||
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
result += L",";
|
||||
v->Append(ref new String(requested_permissions[i]));
|
||||
}
|
||||
|
||||
result += ref new String(requested_permissions[i]);
|
||||
}
|
||||
result->Values = v->GetView();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -162,20 +132,30 @@ BOOL MainPage::DidGetAllRequestedPermissions(
|
|||
return success;
|
||||
}
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
(!result->Succeeded) &&
|
||||
((result->ErrorInfo->Code == (int)Facebook::ErrorCode::ErrorCodeOauthException) &&
|
||||
(result->ErrorInfo->Subcode == (int)Facebook::ErrorSubcode::ErrorSubcodeSessionInvalidated)));
|
||||
}
|
||||
|
||||
BOOL MainPage::ShouldRerequest(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
result->Succeeded &&
|
||||
!DidGetAllRequestedPermissions());
|
||||
}
|
||||
|
||||
void MainPage::NavigateToOptionsPage()
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
|
||||
// We're redirecting to a page that shows simple user info, so
|
||||
// have to dispatch back to the UI thread.
|
||||
CoreWindow^ wind = CoreApplication::MainView->CoreWindow;
|
||||
|
||||
if (wind)
|
||||
{
|
||||
CoreDispatcher^ disp = wind->Dispatcher;
|
||||
if (disp)
|
||||
{
|
||||
disp->RunAsync(
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
|
@ -183,25 +163,62 @@ void MainPage::NavigateToOptionsPage()
|
|||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(OptionsPage::typeid);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task<FBResult^> MainPage::LoginViaRerequest(
|
||||
PropertySet^ Parameters
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
)
|
||||
{
|
||||
Parameters->Insert(L"auth_type", L"rerequest");
|
||||
return create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
// If we're logged out, the session has cleared the FB and Windows app IDs,
|
||||
// so they need to be set again. We load these IDs via the ResourceLoader
|
||||
// class, which must be accessed on the UI thread, which is why this call
|
||||
// is outside the task context.
|
||||
SetSessionAppIds();
|
||||
|
||||
return FBSession::ActiveSession->LoginAsync(Parameters);
|
||||
create_task(FBSession::ActiveSession->LoginAsync(BuildPermissions()))
|
||||
.then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
if (retry && (!DidGetAllRequestedPermissions()))
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(false);
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::LoginButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
void MainPage::LogoutAndRetry(
|
||||
)
|
||||
{
|
||||
// It's necessary to logout prior to reattempting login, because it could
|
||||
// be that the session has cached an access token that is no longer valid,
|
||||
// e.g. if the user revoked the app in Settings. FBSession::Logout clears
|
||||
// the session's cached access token, among other things.
|
||||
create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(TRUE);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
|
@ -215,46 +232,30 @@ void MainPage::LoginButton_Click(Platform::Object^ sender, Windows::UI::Xaml::Ro
|
|||
}
|
||||
else
|
||||
{
|
||||
PropertySet^ parameters = ref new PropertySet();
|
||||
|
||||
parameters->Insert(L"scope", BuildPermissionsString());
|
||||
|
||||
create_task(sess->LoginAsync(parameters)).then([=](FBResult^ result)
|
||||
create_task(sess->LoginAsync(BuildPermissions())).then([=](FBResult^ result)
|
||||
{
|
||||
task<FBResult^> nextResult = create_task([=]()
|
||||
// There may be other cases where an a failed login request should
|
||||
// prompt the app to retry login, but this one is common enough that
|
||||
// it's helpful to demonstrate handling it here. If the predicate
|
||||
// returns TRUE, the user has gone to facebook.com in the browser,
|
||||
// and removed our app from their list off allowed apps in Settings.
|
||||
if (WasAppPermissionRemovedByUser(result))
|
||||
{
|
||||
return result;
|
||||
});
|
||||
|
||||
if ((!result->Succeeded) &&
|
||||
((result->ErrorInfo->Code == 190) && (result->ErrorInfo->Subcode == 466)))
|
||||
{
|
||||
nextResult = LoginViaRerequest(parameters);
|
||||
LogoutAndRetry();
|
||||
}
|
||||
|
||||
return nextResult;
|
||||
})
|
||||
.then([=](FBResult^ loginResult)
|
||||
else if (ShouldRerequest(result))
|
||||
{
|
||||
task<FBResult^> finalResult = create_task([=]()
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
return loginResult;
|
||||
});
|
||||
|
||||
if (loginResult->Succeeded)
|
||||
{
|
||||
if (!DidGetAllRequestedPermissions())
|
||||
{
|
||||
finalResult = LoginViaRerequest(parameters);
|
||||
TryRerequest(FALSE);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
})
|
||||
.then([=](FBResult^ finalResult)
|
||||
{
|
||||
if (finalResult->Succeeded)
|
||||
else if (result && result->Succeeded)
|
||||
{
|
||||
// Got a token, and all the permissions we wanted - go ahead to the options page
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -33,37 +33,37 @@ namespace LoginCpp
|
|||
public:
|
||||
MainPage();
|
||||
|
||||
protected:
|
||||
virtual void OnNavigatedTo(
|
||||
Windows::UI::Xaml::Navigation::NavigationEventArgs^ e
|
||||
) override;
|
||||
|
||||
private:
|
||||
void StartLogin(
|
||||
Facebook::FBSession^ Session
|
||||
);
|
||||
|
||||
void MainPage::SetSessionAppIds(
|
||||
);
|
||||
|
||||
Platform::String^ BuildPermissionsString(
|
||||
Facebook::FBPermissions^ BuildPermissions(
|
||||
);
|
||||
|
||||
BOOL DidGetAllRequestedPermissions(
|
||||
);
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
BOOL ShouldRerequest(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
void NavigateToOptionsPage(
|
||||
);
|
||||
|
||||
concurrency::task<Facebook::FBResult^> MainPage::LoginViaRerequest(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
);
|
||||
|
||||
void LoginButton_Click(
|
||||
Platform::Object^ sender,
|
||||
Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
void MainPage::LogoutAndRetry(
|
||||
);
|
||||
|
||||
Windows::Foundation::EventRegistrationToken m_cookie;
|
||||
void login_OnClicked(
|
||||
Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
);
|
||||
void LoginButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<<<<<<< HEAD
|
||||
<Import Project="..\..\packages\FBWinSDK-debug.0.9.0\build\FBWinSDK-debug.props" Condition="Exists('..\..\packages\FBWinSDK-debug.0.9.0\build\FBWinSDK-debug.props')" />
|
||||
<Import Project="..\..\packages\FBWinSDK.0.9.0\build\win\FBWinSDK.props" Condition="Exists('..\..\packages\FBWinSDK.0.9.0\build\win\FBWinSDK.props')" />
|
||||
=======
|
||||
>>>>>>> 26_change_sample_sdk_references
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
|
|
|
@ -32,6 +32,8 @@ using Windows.UI.Xaml.Navigation;
|
|||
|
||||
using Facebook;
|
||||
using Windows.Globalization;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
|
@ -45,11 +47,14 @@ namespace LoginCs
|
|||
public MainPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
private const string _granted = "granted";
|
||||
private const string FBAppIDName = "FBApplicationId";
|
||||
private const string FBPhoneAppIDName = "FBWinPhoneAppId";
|
||||
private const string PermissionGranted = "granted";
|
||||
|
||||
private string[] requested_permissions =
|
||||
private readonly string[] requested_permissions =
|
||||
{
|
||||
"public_profile",
|
||||
"email",
|
||||
|
@ -57,39 +62,55 @@ namespace LoginCs
|
|||
"publish_actions"
|
||||
};
|
||||
|
||||
private string BuildPermissionsString()
|
||||
{
|
||||
string permissions = "";
|
||||
|
||||
for (uint i = 0; i < requested_permissions.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
permissions += ",";
|
||||
}
|
||||
|
||||
permissions += requested_permissions[i];
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
private bool DidGetRequestedPermissions(
|
||||
void SetSessionAppIds(
|
||||
)
|
||||
{
|
||||
bool gotPermissions = false;
|
||||
uint grantedCount = 0;
|
||||
FBSession s = FBSession.ActiveSession;
|
||||
|
||||
if (FBSession.ActiveSession.AccessTokenData != null)
|
||||
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
|
||||
// in the default resource file.
|
||||
ResourceLoader rl = ResourceLoader.GetForCurrentView();
|
||||
|
||||
String appId = rl.GetString(FBAppIDName);
|
||||
String winAppId = rl.GetString(FBPhoneAppIDName);
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s.FBAppId = appId;
|
||||
s.WinAppId = winAppId;
|
||||
}
|
||||
|
||||
FBPermissions BuildPermissions(
|
||||
)
|
||||
{
|
||||
IReadOnlyDictionary<string, string> Permissions =
|
||||
FBSession.ActiveSession.AccessTokenData.Permissions;
|
||||
FBPermissions result = new FBPermissions();
|
||||
List<string> perms = new List<string>();
|
||||
|
||||
for (uint i = 0; i < requested_permissions.Length; i++)
|
||||
{
|
||||
if (Permissions.ContainsKey(requested_permissions[i]))
|
||||
perms.Add(requested_permissions[i]);
|
||||
}
|
||||
|
||||
result.Values = perms;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DidGetAllRequestedPermissions(
|
||||
)
|
||||
{
|
||||
if (String.CompareOrdinal(Permissions[requested_permissions[i]], _granted) == 0)
|
||||
bool success = false;
|
||||
FBAccessTokenData data = FBSession.ActiveSession.AccessTokenData;
|
||||
uint grantedCount = 0;
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
for (uint i = 0; i < requested_permissions.Length; i++)
|
||||
{
|
||||
string perm = requested_permissions[i];
|
||||
if ((data.Permissions != null) && (data.Permissions.ContainsKey(perm)))
|
||||
{
|
||||
string Value = data.Permissions[perm];
|
||||
if (string.CompareOrdinal(Value, PermissionGranted) == 0)
|
||||
{
|
||||
grantedCount++;
|
||||
}
|
||||
|
@ -98,49 +119,53 @@ namespace LoginCs
|
|||
|
||||
if (grantedCount == requested_permissions.Length)
|
||||
{
|
||||
gotPermissions = true;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
return gotPermissions;
|
||||
return success;
|
||||
}
|
||||
|
||||
private async void LoginToFB()
|
||||
bool WasAppPermissionRemovedByUser(
|
||||
FBResult Result
|
||||
)
|
||||
{
|
||||
Uri endURI =
|
||||
WebAuthenticationBroker.GetCurrentApplicationCallbackUri();
|
||||
string uriString = endURI.ToString();
|
||||
PropertySet parameters = new PropertySet();
|
||||
|
||||
parameters.Add(new KeyValuePair<String, Object>("scope",
|
||||
BuildPermissionsString()));
|
||||
|
||||
FBResult result = await FBSession.ActiveSession.LoginAsync(parameters);
|
||||
if ((!result.Succeeded) &&
|
||||
(((ErrorCode)result.ErrorInfo.Code == ErrorCode.ErrorCodeOauthException) &&
|
||||
((ErrorSubcode)result.ErrorInfo.Subcode == ErrorSubcode.ErrorSubcodeSessionInvalidated)))
|
||||
{
|
||||
parameters.Add(new KeyValuePair<String, Object>("auth_type", "rerequest"));
|
||||
result = await FBSession.ActiveSession.LoginAsync(parameters);
|
||||
return ((Result != null) &&
|
||||
(!Result.Succeeded) &&
|
||||
(Result.ErrorInfo.Code == (int)Facebook.ErrorCode.ErrorCodeOauthException));
|
||||
}
|
||||
|
||||
bool ShouldRerequest(
|
||||
FBResult Result
|
||||
)
|
||||
{
|
||||
return ((Result != null) &&
|
||||
Result.Succeeded &&
|
||||
!DidGetAllRequestedPermissions());
|
||||
}
|
||||
|
||||
async Task TryRerequest(
|
||||
bool Retry
|
||||
)
|
||||
{
|
||||
// If we're logged out, the session has cleared the FB and Windows app IDs,
|
||||
// so they need to be set again. We load these IDs via the ResourceLoader
|
||||
// class, which must be accessed on the UI thread, which is why this call
|
||||
// is outside the task context.
|
||||
SetSessionAppIds();
|
||||
|
||||
FBResult result = await FBSession.ActiveSession.LoginAsync(BuildPermissions());
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
if (DidGetRequestedPermissions())
|
||||
if (Retry && (!DidGetAllRequestedPermissions()))
|
||||
{
|
||||
Frame.Navigate(typeof(UserInfo));
|
||||
await TryRerequest(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!parameters.ContainsKey("auth_type"))
|
||||
{
|
||||
parameters.Add(new KeyValuePair<String, Object>("auth_type", "rerequest"));
|
||||
}
|
||||
result = await FBSession.ActiveSession.LoginAsync(parameters);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
Frame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
//Navigate back to same page, to clear out logged in info.
|
||||
App.RootFrame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +219,27 @@ namespace LoginCs
|
|||
else
|
||||
{
|
||||
LoginButton.Content = "Logout";
|
||||
LoginToFB();
|
||||
FBResult result = await sess.LoginAsync(BuildPermissions());
|
||||
|
||||
// There may be other cases where an a failed login request should
|
||||
// prompt the app to retry login, but this one is common enough that
|
||||
// it's helpful to demonstrate handling it here. If the predicate
|
||||
// returns TRUE, the user has gone to facebook.com in the browser,
|
||||
// and removed our app from their list off allowed apps in Settings.
|
||||
if (WasAppPermissionRemovedByUser(result))
|
||||
{
|
||||
await sess.Logout();
|
||||
await TryRerequest(true);
|
||||
}
|
||||
else if (ShouldRerequest(result))
|
||||
{
|
||||
await TryRerequest(false);
|
||||
}
|
||||
else if (result.Succeeded)
|
||||
{
|
||||
//Navigate back to same page, to clear out logged in info.
|
||||
App.RootFrame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
|
@ -43,43 +44,131 @@ namespace LoginCs
|
|||
{
|
||||
const string FBAppIDName = "FBApplicationId";
|
||||
const string FBPhoneAppIDName = "FBWinPhoneAppId";
|
||||
const string PermissionGranted = "granted";
|
||||
|
||||
readonly string[] requested_permissions =
|
||||
{
|
||||
"public_profile",
|
||||
"user_friends",
|
||||
"user_likes",
|
||||
"user_groups",
|
||||
"user_location"
|
||||
};
|
||||
|
||||
public MainPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
this.NavigationCacheMode = NavigationCacheMode.Required;
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
public async void StartLogin(
|
||||
void SetSessionAppIds(
|
||||
)
|
||||
{
|
||||
FBSession s = FBSession.ActiveSession;
|
||||
|
||||
// Assumes the Facebook App ID and Windows Phone Store ID have been
|
||||
// saved in the default resource file.
|
||||
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
|
||||
// in the default resource file.
|
||||
ResourceLoader rl = ResourceLoader.GetForCurrentView();
|
||||
|
||||
String appId = rl.GetString(FBAppIDName);
|
||||
String winAppId = rl.GetString(FBPhoneAppIDName);
|
||||
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s.FBAppId = appId;
|
||||
s.WinAppId = winAppId;
|
||||
}
|
||||
|
||||
// These are the default permissions, needed to retrieve user info.
|
||||
//s.AddPermission("public_profile");
|
||||
//s.AddPermission("user_friends");
|
||||
//s.AddPermission("user_likes");
|
||||
FBPermissions BuildPermissions(
|
||||
)
|
||||
{
|
||||
FBPermissions result = new FBPermissions();
|
||||
List<string> perms = new List<string>();
|
||||
|
||||
PropertySet parameters = new PropertySet();
|
||||
parameters.Add(
|
||||
new KeyValuePair<string, object>("scope",
|
||||
"public_profile,user_friends,user_likes"));
|
||||
// Launches a URI to redirect to the FB app, which will log us in
|
||||
// and return the result via our registered protocol.
|
||||
FBResult result = await s.LoginAsync();
|
||||
for (uint i = 0; i < requested_permissions.Length; i++)
|
||||
{
|
||||
perms.Add(requested_permissions[i]);
|
||||
}
|
||||
|
||||
result.Values = perms;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DidGetAllRequestedPermissions(
|
||||
)
|
||||
{
|
||||
bool success = false;
|
||||
FBAccessTokenData data = FBSession.ActiveSession.AccessTokenData;
|
||||
uint grantedCount = 0;
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
for (uint i = 0; i < requested_permissions.Length; i++)
|
||||
{
|
||||
string perm = requested_permissions[i];
|
||||
if ((data.Permissions != null) && (data.Permissions.ContainsKey(perm)))
|
||||
{
|
||||
string Value = data.Permissions[perm];
|
||||
if (string.CompareOrdinal(Value, PermissionGranted) == 0)
|
||||
{
|
||||
grantedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (grantedCount == requested_permissions.Length)
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool WasAppPermissionRemovedByUser(
|
||||
FBResult Result
|
||||
)
|
||||
{
|
||||
return ((Result != null) &&
|
||||
(!Result.Succeeded) &&
|
||||
(Result.ErrorInfo.Code == (int)Facebook.ErrorCode.ErrorCodeOauthException));
|
||||
}
|
||||
|
||||
bool ShouldRerequest(
|
||||
FBResult Result
|
||||
)
|
||||
{
|
||||
return ((Result != null) &&
|
||||
Result.Succeeded &&
|
||||
!DidGetAllRequestedPermissions());
|
||||
}
|
||||
|
||||
async Task TryRerequest(
|
||||
bool Retry
|
||||
)
|
||||
{
|
||||
// If we're logged out, the session has cleared the FB and Windows app IDs,
|
||||
// so they need to be set again. We load these IDs via the ResourceLoader
|
||||
// class, which must be accessed on the UI thread, which is why this call
|
||||
// is outside the task context.
|
||||
SetSessionAppIds();
|
||||
|
||||
FBResult result = await FBSession.ActiveSession.LoginAsync(BuildPermissions());
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
if (Retry && (!DidGetAllRequestedPermissions()))
|
||||
{
|
||||
await TryRerequest(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Navigate back to same page, to clear out logged in info.
|
||||
App.RootFrame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -127,7 +216,27 @@ namespace LoginCs
|
|||
else
|
||||
{
|
||||
LoginButton.Content = "Logout";
|
||||
StartLogin();
|
||||
|
||||
FBResult result = await sess.LoginAsync(BuildPermissions());
|
||||
|
||||
// There may be other cases where an a failed login request should
|
||||
// prompt the app to retry login, but this one is common enough that
|
||||
// it's helpful to demonstrate handling it here. If the predicate
|
||||
// returns TRUE, the user has gone to facebook.com in the browser,
|
||||
// and removed our app from their list off allowed apps in Settings.
|
||||
if (WasAppPermissionRemovedByUser(result))
|
||||
{
|
||||
await sess.Logout();
|
||||
}
|
||||
else if (ShouldRerequest(result))
|
||||
{
|
||||
await TryRerequest(false);
|
||||
}
|
||||
else if (result.Succeeded)
|
||||
{
|
||||
//Navigate back to same page, to clear out logged in info.
|
||||
App.RootFrame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче