Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ jobs:
permissions:
contents: read
env:
UNIGETUI_GITHUB_CLIENT_ID: ${{ secrets.UNIGETUI_GITHUB_CLIENT_ID }}
UNIGETUI_GITHUB_CLIENT_SECRET: ${{ secrets.UNIGETUI_GITHUB_CLIENT_SECRET }}
NUGET_PACKAGES: ${{ github.workspace }}\.nuget\packages
strategy:
fail-fast: false
Expand All @@ -99,6 +101,19 @@ jobs:
- name: Checkout
uses: actions/checkout@v6

- name: Validate GitHub OAuth secrets
shell: pwsh
run: |
if ([string]::IsNullOrWhiteSpace($env:UNIGETUI_GITHUB_CLIENT_ID)) {
throw "UNIGETUI_GITHUB_CLIENT_ID is not configured for this build environment."
}
if ([string]::IsNullOrWhiteSpace($env:UNIGETUI_GITHUB_CLIENT_SECRET)) {
throw "UNIGETUI_GITHUB_CLIENT_SECRET is not configured for this build environment."
}
Write-Host "::notice::GitHub OAuth secrets are configured for this build."
- name: Install .NET
uses: actions/setup-dotnet@v5
with:
Expand Down
2 changes: 1 addition & 1 deletion src/UniGetUI/Pages/DialogPages/DialogHelper_Generic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ public static async Task ShowTelemetryDialog()
p.Inlines.Add(new LineBreak());
var link = new Hyperlink
{
NavigateUri = new Uri("https://www.marticliment.com/unigetui/privacy/"),
NavigateUri = new Uri("https://devolutions.net/legal/"),
};
link.Inlines.Add(
new Run
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ private void EnablePackageBackupCheckBox_CLOUD_StateChanged(object? sender, Even

private void MoreInfoBtn_OnClick(object sender, RoutedEventArgs e)
{
MainApp.Instance.MainWindow.NavigationPage.ShowHelp("cloud-backup-overview/");
CoreTools.Launch("https://devolutions.net/unigetui");
}
}
}
66 changes: 60 additions & 6 deletions src/UniGetUI/Services/GitHubAuthService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace UniGetUI.Services
{
public class GitHubAuthService
{
private const string MissingClientId = "CLIENT_ID_UNSET";
private const string MissingClientSecret = "CLIENT_SECRET_UNSET";
private static readonly TimeSpan LoginTimeout = TimeSpan.FromMinutes(2);
private readonly string GitHubClientId = Secrets.GetGitHubClientId();
private readonly string GitHubClientSecret = Secrets.GetGitHubClientSecret();
private const string RedirectUri = "http://127.0.0.1:58642/";
Expand Down Expand Up @@ -47,6 +50,15 @@ public async Task<bool> SignInAsync()
{
try
{
if (!HasConfiguredOAuthClient())
{
Logger.Error(
"GitHub sign-in is not configured for this build. Missing OAuth client ID or client secret."
);
AuthStatusChanged?.Invoke(this, EventArgs.Empty);
return false;
}

Logger.Info("Initiating GitHub sign-in process using loopback redirect...");

var request = new OauthLoginRequest(GitHubClientId)
Expand Down Expand Up @@ -74,15 +86,25 @@ public async Task<bool> SignInAsync()
loginBackend = new GHAuthApiRunner();
loginBackend.OnLogin += BackgroundApiOnOnLogin;
await loginBackend.Start();
await Launcher.LaunchUriAsync(oauthLoginUrl);

while (codeFromAPI is null)
bool launchSucceeded = await Launcher.LaunchUriAsync(oauthLoginUrl);
if (!launchSucceeded)
{
Logger.Error("Failed to launch the browser for GitHub sign-in.");
AuthStatusChanged?.Invoke(this, EventArgs.Empty);
return false;
}

DateTime timeoutAt = DateTime.UtcNow.Add(LoginTimeout);
while (codeFromAPI is null && DateTime.UtcNow < timeoutAt)
await Task.Delay(100);

loginBackend.OnLogin -= BackgroundApiOnOnLogin;
await loginBackend.Stop();
loginBackend.Dispose();
loginBackend = null;
if (string.IsNullOrEmpty(codeFromAPI))
{
Logger.Error("GitHub sign-in timed out before the loopback callback was received.");
AuthStatusChanged?.Invoke(this, EventArgs.Empty);
return false;
}

return await _completeSignInAsync(codeFromAPI);
}
Expand All @@ -94,6 +116,26 @@ public async Task<bool> SignInAsync()
AuthStatusChanged?.Invoke(this, EventArgs.Empty);
return false;
}
finally
{
if (loginBackend is not null)
{
try
{
loginBackend.OnLogin -= BackgroundApiOnOnLogin;
await loginBackend.Stop();
loginBackend.Dispose();
}
catch (Exception ex)
{
Logger.Warn(ex);
}
finally
{
loginBackend = null;
}
}
}
}

private string? codeFromAPI;
Expand All @@ -103,6 +145,18 @@ private void BackgroundApiOnOnLogin(object? sender, string c)
codeFromAPI = c;
}

private bool HasConfiguredOAuthClient()
{
return !string.IsNullOrWhiteSpace(GitHubClientId)
&& !string.IsNullOrWhiteSpace(GitHubClientSecret)
&& !string.Equals(GitHubClientId, MissingClientId, StringComparison.Ordinal)
&& !string.Equals(
GitHubClientSecret,
MissingClientSecret,
StringComparison.Ordinal
);
}

private async Task<bool> _completeSignInAsync(string code)
{
try
Expand Down
13 changes: 10 additions & 3 deletions src/UniGetUI/Services/UserAvatar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,14 @@ private async Task _loginButton_Click()
return;
}

await client.SignInAsync();
bool success = await client.SignInAsync();
if (!success)
{
DialogHelper.ShowDismissableBalloon(
CoreTools.Translate("Failed"),
CoreTools.Translate("An error occurred while logging in: ")
);
}
}
catch (Exception ex)
{
Expand Down Expand Up @@ -132,7 +139,7 @@ private PointButton GenerateLoginControl()
FontSize = 12,
};
hyperlinkButton.Click += (_, _) =>
MainApp.Instance.MainWindow.NavigationPage.ShowHelp("cloud-backup-overview/");
CoreTools.Launch("https://devolutions.net/unigetui");

var loginButton = new PointButton
{
Expand Down Expand Up @@ -235,7 +242,7 @@ private async Task<PointButton> GenerateLogoutControl()
FontSize = 12,
};
hyperlinkButton.Click += (_, _) =>
MainApp.Instance.MainWindow.NavigationPage.ShowHelp("cloud-backup-overview/");
CoreTools.Launch("https://devolutions.net/unigetui");

var hyperlinkButton2 = new HyperlinkButton
{
Expand Down
8 changes: 4 additions & 4 deletions src/UniGetUI/Services/generate-secrets.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ if (-not (Test-Path -Path "Generated Files")) {
}


$clientId = $env:GH_UGUI_CLIENT_ID
$clientSecret = $env:GH_UGUI_CLIENT_SECRET
$clientId = $env:UNIGETUI_GITHUB_CLIENT_ID
$clientSecret = $env:UNIGETUI_GITHUB_CLIENT_SECRET

if (-not $clientId) { $clientId = "CLIENT_ID_UNSET" }
if (-not $clientSecret) { $clientSecret = "CLIENT_SECRET_UNSET" }

@"
// Auto-generated file - do not modidy
// Auto-generated file - do not modify
namespace UniGetUI.Services
{
internal static partial class Secrets
Expand All @@ -29,4 +29,4 @@ namespace UniGetUI.Services
}
}
"@ | Set-Content -Encoding UTF8 "Generated Files\Secrets.Generated.cs"
cp "Generated Files\Secrets.Generated.cs" "$OutputPath\Generated Files\Secrets.Generated.cs"
Copy-Item "Generated Files\Secrets.Generated.cs" "$OutputPath\Generated Files\Secrets.Generated.cs"
Loading