diff --git a/rubberduckvba.Server/Api/Admin/AdminController.cs b/rubberduckvba.Server/Api/Admin/AdminController.cs
index 4993c72..cf48508 100644
--- a/rubberduckvba.Server/Api/Admin/AdminController.cs
+++ b/rubberduckvba.Server/Api/Admin/AdminController.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
@@ -13,6 +14,7 @@ public class AdminController(ConfigurationOptions options, HangfireLauncherServi
///
/// The unique identifier of the enqueued job.
[Authorize("github")]
+ [EnableCors("CorsPolicy")]
[HttpPost("admin/update/xmldoc")]
public IActionResult UpdateXmldocContent()
{
@@ -25,6 +27,7 @@ public IActionResult UpdateXmldocContent()
///
/// The unique identifier of the enqueued job.
[Authorize("github")]
+ [EnableCors("CorsPolicy")]
[HttpPost("admin/update/tags")]
public IActionResult UpdateTagMetadata()
{
diff --git a/rubberduckvba.Server/Api/Admin/WebhookController.cs b/rubberduckvba.Server/Api/Admin/WebhookController.cs
index 8f99aab..6ded8a6 100644
--- a/rubberduckvba.Server/Api/Admin/WebhookController.cs
+++ b/rubberduckvba.Server/Api/Admin/WebhookController.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
@@ -21,6 +22,7 @@ public WebhookController(
}
[Authorize("webhook")]
+ [EnableCors("webhookPolicy")]
[HttpPost("webhook/github")]
public async Task GitHub([FromBody] dynamic body) =>
GuardInternalAction(() =>
diff --git a/rubberduckvba.Server/Api/Auth/AuthController.cs b/rubberduckvba.Server/Api/Auth/AuthController.cs
index 05a8818..92247ab 100644
--- a/rubberduckvba.Server/Api/Auth/AuthController.cs
+++ b/rubberduckvba.Server/Api/Auth/AuthController.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Octokit;
@@ -70,6 +71,7 @@ public IActionResult Index()
}
[HttpPost("auth/signin")]
+ [EnableCors("CorsPolicy")]
[AllowAnonymous]
public IActionResult SessionSignIn(SignInViewModel vm)
{
@@ -106,6 +108,7 @@ public IActionResult SessionSignIn(SignInViewModel vm)
}
[HttpPost("auth/github")]
+ [EnableCors("CorsPolicy")]
[AllowAnonymous]
public IActionResult OnGitHubCallback(SignInViewModel vm)
{
diff --git a/rubberduckvba.Server/ContentSynchronization/Pipeline/Sections/SyncTags/LoadGitHubTagsBlock.cs b/rubberduckvba.Server/ContentSynchronization/Pipeline/Sections/SyncTags/LoadGitHubTagsBlock.cs
index d9dfc63..1fca8e9 100644
--- a/rubberduckvba.Server/ContentSynchronization/Pipeline/Sections/SyncTags/LoadGitHubTagsBlock.cs
+++ b/rubberduckvba.Server/ContentSynchronization/Pipeline/Sections/SyncTags/LoadGitHubTagsBlock.cs
@@ -16,7 +16,7 @@ public LoadGitHubTagsBlock(PipelineSection parent, CancellationToke
public override async Task TransformAsync(SyncRequestParameters input)
{
- var githubTags = await _github.GetAllTagsAsync(); // does not get the assets
+ var githubTags = await _github.GetAllTagsAsync(Context.RubberduckDbMain.Name);
var (gitHubMain, gitHubNext, gitHubOthers) = githubTags.GetLatestTags();
Context.LoadGitHubTags(gitHubMain, gitHubNext, gitHubOthers);
diff --git a/rubberduckvba.Server/ContentSynchronization/Pipeline/Sections/SyncXmldoc/SyncXmldocSection.cs b/rubberduckvba.Server/ContentSynchronization/Pipeline/Sections/SyncXmldoc/SyncXmldocSection.cs
index 3cd19de..0aa4ab9 100644
--- a/rubberduckvba.Server/ContentSynchronization/Pipeline/Sections/SyncXmldoc/SyncXmldocSection.cs
+++ b/rubberduckvba.Server/ContentSynchronization/Pipeline/Sections/SyncXmldoc/SyncXmldocSection.cs
@@ -90,7 +90,8 @@ protected override async Task ActionAsync(SyncRequestParameters input)
{
Context.LoadParameters(input);
- var githubTags = await _github.GetAllTagsAsync();
+ var dbMain = await _content.GetLatestTagAsync(RepositoryId.Rubberduck, includePreRelease: false);
+ var githubTags = await _github.GetAllTagsAsync(dbMain.Name);
// LoadInspectionDefaultConfig
var config = await _github.GetCodeAnalysisDefaultsConfigAsync();
@@ -115,7 +116,6 @@ await Task.WhenAll([
await Task.Delay(TimeSpan.FromSeconds(2)); // just in case the tags job was scheduled at/around the same time
- var dbMain = await _content.GetLatestTagAsync(RepositoryId.Rubberduck, includePreRelease: false);
var dbNext = await _content.GetLatestTagAsync(RepositoryId.Rubberduck, includePreRelease: true);
var dbTags = _tagServices.GetAllTags().ToDictionary(e => e.Name);
diff --git a/rubberduckvba.Server/Program.cs b/rubberduckvba.Server/Program.cs
index 3bc58fb..7c628c5 100644
--- a/rubberduckvba.Server/Program.cs
+++ b/rubberduckvba.Server/Program.cs
@@ -45,7 +45,7 @@ public static void Main(string[] args)
builder.Services.AddCors(builder =>
{
- builder.AddDefaultPolicy(policy =>
+ builder.AddPolicy("CorsPolicy", policy =>
{
policy
.SetIsOriginAllowed(origin => true)
@@ -54,22 +54,6 @@ public static void Main(string[] args)
.AllowCredentials()
.Build();
});
-
- builder.AddPolicy("webhookPolicy", policy =>
- {
- policy
-#if DEBUG
- .SetIsOriginAllowed(origin => true)
-#else
- .SetIsOriginAllowedToAllowWildcardSubdomains()
- .WithOrigins("*.github.com")
-#endif
- .WithHeaders("Content-Type", "X-GitHub-Event", "X-GitHub-Delivery", "X-GitHub-Hook-ID", "X-Hub-Signature", "X-Hub-Signature256")
- .WithMethods("POST")
- .DisallowCredentials()
- .SetPreflightMaxAge(TimeSpan.FromHours(48))
- .Build();
- });
});
builder.Services.AddAuthentication(options =>
diff --git a/rubberduckvba.Server/Services/GitHubClientService.cs b/rubberduckvba.Server/Services/GitHubClientService.cs
index 6260e96..479c131 100644
--- a/rubberduckvba.Server/Services/GitHubClientService.cs
+++ b/rubberduckvba.Server/Services/GitHubClientService.cs
@@ -6,6 +6,7 @@
using rubberduckvba.Server.ContentSynchronization.XmlDoc.Schema;
using rubberduckvba.Server.Model;
using System.Collections.Immutable;
+using System.Diagnostics.CodeAnalysis;
using System.Security.Claims;
using System.Text;
using System.Web;
@@ -16,13 +17,20 @@ namespace rubberduckvba.Server.Services;
public interface IGitHubClientService
{
Task ValidateTokenAsync(string token);
- Task> GetAllTagsAsync();
+ Task> GetAllTagsAsync(string? dbMainTagName);
Task GetTagAsync(string? token, string name);
Task> GetCodeAnalysisDefaultsConfigAsync();
}
public class GitHubClientService(IOptions configuration, ILogger logger) : IGitHubClientService
{
+ private class ReleaseComparer : IEqualityComparer
+ {
+ public bool Equals(Release? x, Release? y) => x?.Name == y?.Name;
+
+ public int GetHashCode([DisallowNull] Release obj) => HashCode.Combine(obj.Name);
+ }
+
public async Task ValidateTokenAsync(string? token)
{
if (token is null)
@@ -52,13 +60,18 @@ public class GitHubClientService(IOptions configuration, ILogger
return new ClaimsPrincipal(identity);
}
- public async Task> GetAllTagsAsync()
+ public async Task> GetAllTagsAsync(string? dbMainTagName)
{
var config = configuration.Value;
var credentials = new Credentials(config.OrgToken);
var client = new GitHubClient(new ProductHeaderValue(config.UserAgent), new InMemoryCredentialStore(credentials));
- var releases = await client.Repository.Release.GetAll(config.OwnerOrg, config.Rubberduck, new ApiOptions { PageCount = 1, PageSize = 10 });
+
+ var getReleases = client.Repository.Release.GetAll(config.OwnerOrg, config.Rubberduck, new ApiOptions { PageCount = 1, PageSize = 10 });
+ var getKnownMain = client.Repository.Release.Get(config.OwnerOrg, config.Rubberduck, dbMainTagName);
+ await Task.WhenAll(getReleases, getKnownMain);
+
+ var releases = (await getReleases).Append(await getKnownMain).ToHashSet(new ReleaseComparer());
return (from release in releases
let installer = release.Assets.SingleOrDefault(asset => asset.Name.EndsWith(".exe") && asset.Name.StartsWith("Rubberduck.Setup"))