<StackPanel Grid.Column="1">
<StackPanel Orientation="Horizontal">
<Button Width="100" Height="23" Margin="2" Command="{Binding AuthLogin}" Content="Auth Login" />
<Button x:Name="AuthLogoutButton" Width="100" Height="23" Margin="2" Command="{Binding AuthLogout}" Content="Auth Logout" />
</StackPanel>
<Button x:Name="ConnectLoginButton" HorizontalAlignment="Right" Width="100" Height="23" Margin="2" Command="{Binding ConnectLogin}" Content="Connect Login" />
</StackPanel>
<StackPanel Grid.Column="0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="AccountId:" Margin="2" />
<TextBox Text="{Binding AccountId}" IsReadOnly="True" Margin="2" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="DisplayName:" Margin="2" />
<TextBox Text="{Binding DisplayName}" IsReadOnly="True" Margin="2" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="ProductUserId:" Margin="2" />
<TextBox Text="{Binding ProductUserId}" IsReadOnly="True" Margin="2" />
</StackPanel>
</StackPanel>
private string _productUserId;
public string ProductUserId
{
get { return _productUserId; }
set { SetProperty(ref _productUserId, value); }
}
private ulong _connectAuthExpirationNotificationId;
public ulong ConnectAuthExpirationNotificationId
{
get { return _connectAuthExpirationNotificationId; }
set { SetProperty(ref _connectAuthExpirationNotificationId, value); }
}
private ulong _connectLoginStatusChangedNotificationId;
public ulong ConnectLoginStatusChangedNotificationId
{
get { return _connectLoginStatusChangedNotificationId; }
set { SetProperty(ref _connectLoginStatusChangedNotificationId, value); }
public class ConnectLoginCommand : CommandBase
{
public override bool CanExecute(object parameter)
{
return !string.IsNullOrWhiteSpace(ViewModelLocator.Main.AccountId) && string
.IsNullOrWhiteSpace(ViewModelLocator.Main.ProductUserId);
}
public override void Execute(object parameter)
{
ConnectService.ConnectLogin();
}
}
public static class ConnectService
{
public static void ConnectLogin()
{
ViewModelLocator.Main.StatusBarText = "Getting auth interface...";
var authInterface = App.Settings.PlatformInterface.GetAuthInterface();
if (authInterface == null)
{
Debug.WriteLine("Failed to get auth interface");
ViewModelLocator.Main.StatusBarText = string.Empty;
return;
}
var copyIdTokenOptions = new Epic.OnlineServices.Auth.CopyIdTokenOptions()
{
AccountId = EpicAccountId.FromString(ViewModelLocator.Main.AccountId)
};
var result = authInterface.CopyIdToken(copyIdTokenOptions, out var userAuthToken);
if (result == Result.Success)
{
var connectInterface = App.Settings.PlatformInterface.GetConnectInterface();
if (connectInterface == null)
{
Debug.WriteLine("Failed to get connect interface");
return;
}
var loginOptions = new LoginOptions()
{
Credentials = new Credentials()
{
Type = ExternalCredentialType.EpicIdToken,
Token = userAuthToken.JsonWebToken
}
};
ViewModelLocator.Main.StatusBarText = "Requesting user login...";
// Ensure platform tick is called on an interval, or the following call will never callback.
connectInterface.Login(loginOptions, null, (LoginCallbackInfo loginCallbackInfo)=>
{
Debug.WriteLine($"Connect login {loginCallbackInfo.ResultCode}");
if (loginCallbackInfo.ResultCode == Result.Success)
{
ViewModelLocator.Main.StatusBarText = "Connect login successful.";
ViewModelLocator.Main.ConnectAuthExpirationNotificationId = connectInterface.AddNotifyAuthExpiration(new AddNotifyAuthExpirationOptions(), null, AuthExpirationCallback);
ViewModelLocator.Main.ConnectLoginStatusChangedNotificationId = connectInterface.AddNotifyLoginStatusChanged(new AddNotifyLoginStatusChangedOptions(), null, LoginStatusChangedCallback);
ViewModelLocator.Main.ProductUserId = loginCallbackInfo.LocalUserId.ToString();
}
else if (loginCallbackInfo.ResultCode == Result.InvalidUser)
{
ViewModelLocator.Main.StatusBarText = "Connect login failed: " + loginCallbackInfo.ResultCode;
var loginWithDifferentCredentials = MessageBox.Show("User not found. Log in with different credentials?", "Invalid User", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (loginWithDifferentCredentials == MessageBoxResult.No)
{
var createUserOptions = new CreateUserOptions()
{
ContinuanceToken = loginCallbackInfo.ContinuanceToken
};
connectInterface.CreateUser(createUserOptions, null, (CreateUserCallbackInfo createUserCallbackInfo) =>
{
if (createUserCallbackInfo.ResultCode == Result.Success)
{
ViewModelLocator.Main.StatusBarText = "User successfully created.";
ViewModelLocator.Main.ConnectAuthExpirationNotificationId = connectInterface
.AddNotifyAuthExpiration(new AddNotifyAuthExpirationOptions(), null, AuthExpirationCallback);
ViewModelLocator.Main.ConnectLoginStatusChangedNotificationId = connectInterface
.AddNotifyLoginStatusChanged(new AddNotifyLoginStatusChangedOptions(), null, LoginStatusChangedCallback);
ViewModelLocator.Main.ProductUserId = createUserCallbackInfo.LocalUserId.ToString();
}
else if (Common.IsOperationComplete(loginCallbackInfo.ResultCode))
{
Debug.WriteLine("User creation failed: " + createUserCallbackInfo.ResultCode);
}
ViewModelLocator.Main.StatusBarText = string.Empty;
ViewModelLocator.RaiseConnectCanExecuteChanged();
});
}
else
{
// Prompt for login with different credentials
}
}
else if (Common.IsOperationComplete(loginCallbackInfo.ResultCode))
{
Debug.WriteLine("Connect login failed: " + loginCallbackInfo.ResultCode);
}
ViewModelLocator.Main.StatusBarText = string.Empty;
ViewModelLocator.RaiseConnectCanExecuteChanged();
});
}
else if (Common.IsOperationComplete(result))
{
Debug.WriteLine("CopyIdToken failed: " + result);
ViewModelLocator.Main.StatusBarText = string.Empty;
}
}
private static void AuthExpirationCallback(AuthExpirationCallbackInfo data)
{
// Handle 10-minute warning prior to token expiration by calling Connect.Login()
}
private static void LoginStatusChangedCallback(LoginStatusChangedCallbackInfo data)
{
switch (data.CurrentStatus)
{
case LoginStatus.NotLoggedIn:
if (data.PreviousStatus == LoginStatus.LoggedIn)
{
// Handle token expiration
}
break;
case LoginStatus.UsingLocalProfile:
break;
case LoginStatus.LoggedIn:
break;
}
}
public static void RemoveNotifications()
{
App.Settings.PlatformInterface.GetConnectInterface()
.RemoveNotifyAuthExpiration(ViewModelLocator.Main
.ConnectAuthExpirationNotificationId);
App.Settings.PlatformInterface.GetConnectInterface()
.RemoveNotifyLoginStatusChanged(ViewModelLocator.Main
.ConnectLoginStatusChangedNotificationId);
}
}
ConnectService.RemoveNotifications();
public ConnectLoginCommand ConnectLogin { get; set; }
public MainViewModel()
{
AuthLogin = new AuthLoginCommand();
AuthLogout = new AuthLogoutCommand();
ConnectLogin = new ConnectLoginCommand();
}
private ulong _connectAuthExpirationNotificationId;
public ulong ConnectAuthExpirationNotificationId
{
get { return _connectAuthExpirationNotificationId; }
set { SetProperty(ref _connectAuthExpirationNotificationId, value); }
}
private ulong _connectLoginStatusChangedNotificationId;
public ulong ConnectLoginStatusChangedNotificationId
{
get { return _connectLoginStatusChangedNotificationId; }
set { SetProperty(ref _connectLoginStatusChangedNotificationId, value); }
}
public static void RaiseConnectCanExecuteChanged()
{
Main.ConnectLogin.RaiseCanExecuteChanged();
}
Main.ConnectLogin.RaiseCanExecuteChanged();