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
6 changes: 3 additions & 3 deletions .github/workflows/bit.full.ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: bit platform full CI
name: bit platform full CI

on:
workflow_dispatch:
Expand Down Expand Up @@ -187,13 +187,13 @@ jobs:

- name: Test sample configuration 1
run: |
dotnet new bit-bp --name TestProject --database SqlServer --filesStorage AzureBlobStorage --api Integrated --captcha reCaptcha --pipeline Azure --module Admin --offlineDb --appInsights --sentry --signalR --notification --cloudflare --ads
dotnet new bit-bp --name TestProject --database SqlServer --filesStorage AzureBlobStorage --api Integrated --captcha reCaptcha --pipeline Azure --module Admin --offlineDb --appInsights --sentry --signalR --notification --cloudflare --ads --aspire
dotnet build TestProject/TestProject.sln -p:InvariantGlobalization=false -p:Environment=Staging
rm -r "TestProject"

- name: Test sample configuration 2
run: |
dotnet new bit-bp --name TestProject2 --database Other --filesStorage Other --api Standalone --captcha None --pipeline None --module None --offlineDb false --appInsights false --sentry false --signalR false --notification false --cloudflare false --ads false
dotnet new bit-bp --name TestProject2 --database Other --filesStorage S3 --api Standalone --captcha None --pipeline None --module None --offlineDb false --appInsights false --sentry false --signalR false --notification false --cloudflare false --ads false --aspire false
dotnet build TestProject2/TestProject2.sln -p:InvariantGlobalization=true -p:Environment=Development
rm -r "TestProject2"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
{
"id": "helpUrl"
},
{
"id": "aspire"
},
{
"id": "database"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
"choice": "Local",
"description": "Use either the local App_Data folder or the /container_volume for Docker containers."
},
{
"choice": "S3",
"description": "S3"
},
{
"choice": "AzureBlobStorage",
"description": "Azure blob storage"
Expand Down Expand Up @@ -162,6 +166,13 @@
}
]
},
"aspire": {
"displayName": "Add aspire?",
"type": "parameter",
"datatype": "bool",
"defaultValue": "false",
"description": "Adds aspire"
},
"notification": {
"displayName": "Add push notification?",
"type": "parameter",
Expand Down Expand Up @@ -264,6 +275,33 @@
},
"replaces": "5030"
},
"aspirePortGenerated_1": {
"type": "generated",
"generator": "port",
"parameters": {
"low": 2001,
"high": 2300
},
"replaces": "2030"
},
"aspirePortGenerated_2": {
"type": "generated",
"generator": "port",
"parameters": {
"low": 2001,
"high": 2300
},
"replaces": "2031"
},
"aspirePortGenerated_3": {
"type": "generated",
"generator": "port",
"parameters": {
"low": 2001,
"high": 2300
},
"replaces": "2032"
},
"serveApiPortGenerated": {
"type": "generated",
"generator": "port",
Expand Down Expand Up @@ -377,7 +415,7 @@
"**/*.svg",
"**/*.png",
"**/*.sh",
".github/copilot-instructions.md"
".github/copilot-instructions.md"
],
"exclude": [
".vs/**",
Expand Down Expand Up @@ -559,9 +597,13 @@
"condition": "(api == Integrated)",
"exclude": [
"src/Server/Boilerplate.Server.Web/appsettings*.json",
"src/Server/Boilerplate.Server.Web/Services/AppResponseCachePolicy.cs",
"src/Server/Boilerplate.Server.Web/Services/SimpleJwtSecureDataFormat.cs",
"src/Server/Boilerplate.Server.Web/Extensions/HttpContextExtensions.cs"
"src/Server/Boilerplate.Server.Web/Services/SimpleJwtSecureDataFormat.cs"
]
},
{
"condition": "(aspire == false)",
"exclude": [
"src/Server/Boilerplate.Server.AppHost/**"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
"projects": [
"src\\Client\\Boilerplate.Client.Core\\Boilerplate.Client.Core.csproj",
"src\\Client\\Boilerplate.Client.Web\\Boilerplate.Client.Web.csproj",
//#if (aspire == true)
"src\\Server\\Boilerplate.Server.AppHost\\Boilerplate.Server.AppHost.csproj",
//#endif
"src\\Server\\Boilerplate.Server.Api\\Boilerplate.Server.Api.csproj",
"src\\Server\\Boilerplate.Server.Shared\\Boilerplate.Server.Shared.csproj",
"src\\Server\\Boilerplate.Server.Web\\Boilerplate.Server.Web.csproj",
"src\\Shared\\Boilerplate.Shared.csproj",
"src\\Tests\\Boilerplate.Tests.csproj"
Expand Down
20 changes: 20 additions & 0 deletions src/Templates/Boilerplate/Bit.Boilerplate/Boilerplate.sln
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31611.283
MinimumVisualStudioVersion = 10.0.40219.1
#if (aspire == true)
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boilerplate.Server.AppHost", "src\Server\Boilerplate.Server.AppHost\Boilerplate.Server.AppHost.csproj", "{C1CACA9D-8E95-5A02-3E37-37CE607581A3}"
EndProject
//#endif
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Server.Web", "src\Server\Boilerplate.Server.Web\Boilerplate.Server.Web.csproj", "{8CC3E410-B716-4F4D-89C7-3392CA624439}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boilerplate.Server.Shared", "src\Server\Boilerplate.Server.Shared\Boilerplate.Server.Shared.csproj", "{AA97E5DE-1021-2739-ED90-9EDEEAEB5CA2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".SolutionItems", ".SolutionItems", "{5CF43F76-BB71-4B5B-B4DF-1C753E042A8F}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
Expand Down Expand Up @@ -103,6 +109,16 @@ Global
{3D93B170-BDCD-4890-92B3-F5ABE48F3D3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D93B170-BDCD-4890-92B3-F5ABE48F3D3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D93B170-BDCD-4890-92B3-F5ABE48F3D3A}.Release|Any CPU.Build.0 = Release|Any CPU
{AA97E5DE-1021-2739-ED90-9EDEEAEB5CA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA97E5DE-1021-2739-ED90-9EDEEAEB5CA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA97E5DE-1021-2739-ED90-9EDEEAEB5CA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA97E5DE-1021-2739-ED90-9EDEEAEB5CA2}.Release|Any CPU.Build.0 = Release|Any CPU
#if (aspire == true)
{C1CACA9D-8E95-5A02-3E37-37CE607581A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1CACA9D-8E95-5A02-3E37-37CE607581A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1CACA9D-8E95-5A02-3E37-37CE607581A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1CACA9D-8E95-5A02-3E37-37CE607581A3}.Release|Any CPU.Build.0 = Release|Any CPU
//#endif
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -123,6 +139,10 @@ Global
{2347E3B2-FDDE-427E-A0AE-E4DCD47C2989} = {3E577755-186F-4E63-8153-B8DE890015C9}
#endif
{E3CB3C34-F5DE-4A96-B552-7D52BCAD1E1F} = {248D8229-BABD-4F0A-A9C6-0417B464507B}
{AA97E5DE-1021-2739-ED90-9EDEEAEB5CA2} = {723683EA-193C-45FD-A64D-7830A2867E4F}
#if (aspire == true)
{C1CACA9D-8E95-5A02-3E37-37CE607581A3} = {723683EA-193C-45FD-A64D-7830A2867E4F}
#endif
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
Expand Down
12 changes: 8 additions & 4 deletions src/Templates/Boilerplate/Bit.Boilerplate/Boilerplate.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,28 @@
<File Path="src/Directory.Packages.props" />
</Folder>
//#if (pipeline == "Azure")
<Folder Name="/.SolutionItems/.azure-devops/" Id="3f1dd063-d3a3-f428-24f8-626958d189fb" />
<Folder Name="/.SolutionItems/.azure-devops/workflows/" Id="d5673a47-b807-7464-ee0f-fd95c5542ac5">
<Folder Name="/.SolutionItems/.azure-devops/" />
<Folder Name="/.SolutionItems/.azure-devops/workflows/">
<File Path=".azure-devops/workflows/cd.yml" />
<File Path=".azure-devops/workflows/ci.yml" />
</Folder>
//#endif
<Folder Name="/.SolutionItems/.github/" Id="351df30f-2daa-a858-be55-4affc8d70af2">
<Folder Name="/.SolutionItems/.github/">
<File Path=".github/copilot-instructions.md" />
</Folder>
//#if (pipeline == "GitHub")
<Folder Name="/.SolutionItems/.github/workflows/" Id="c0ca9c70-aac5-bd27-2f07-59fab982d30d">
<Folder Name="/.SolutionItems/.github/workflows/">
<File Path=".github/workflows/cd.yml" />
<File Path=".github/workflows/ci.yml" />
</Folder>
//#endif
<Folder Name="/Server/">
<Project Path="src/Server/Boilerplate.Server.Web/Boilerplate.Server.Web.csproj" />
<Project Path="src/Server/Boilerplate.Server.Api/Boilerplate.Server.Api.csproj" />
<Project Path="src/Server/Boilerplate.Server.Shared/Boilerplate.Server.Shared.csproj" />
//#if (aspire == true)
<Project Path="src/Server/Boilerplate.Server.AppHost/Boilerplate.Server.AppHost.csproj" />
//#endif
</Folder>
<Folder Name="/Client/">
<Project Path="src/Client/Boilerplate.Client.Core/Boilerplate.Client.Core.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@
<PackageVersion Include="Microsoft.Extensions.Logging.EventLog" Version="9.0.6" />
<PackageVersion Include="Microsoft.Extensions.Logging.EventSource" Version="9.0.6" />
<!--/+:msbuild-conditional:noEmit -->
<PackageVersion Condition=" '$(aspire)' == 'true' OR '$(aspire)' == '' " Include="Aspire.Hosting.AppHost" Version="9.3.1" />
<PackageVersion Condition=" ('$(aspire)' == 'true' OR '$(aspire)' == '') AND ('$(database)' == 'SqlServer' OR '$(database)' == '') " Include="Aspire.Hosting.SqlServer" Version="9.3.2" />
<PackageVersion Condition=" ('$(aspire)' == 'true' OR '$(aspire)' == '') AND ('$(database)' == 'PostgreSQL' OR '$(database)' == '') " Include="Aspire.Hosting.PostgreSQL" Version="9.3.1" />
<PackageVersion Condition=" ('$(aspire)' == 'true' OR '$(aspire)' == '') AND ('$(database)' == 'MySql' OR '$(database)' == '') " Include="Aspire.Hosting.MySql" Version="9.3.1" />
<PackageVersion Condition=" ('$(aspire)' == 'true' OR '$(aspire)' == '') AND ('$(filesStorage)' == 'AzureBlobStorage' OR '$(filesStorage)' == '') " Include="Aspire.Hosting.Azure.Storage" Version="9.3.1" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="9.6.0" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="9.3.1" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.12.0" />
<PackageVersion Include="Hangfire.AspNetCore" Version="1.8.20" />
<PackageVersion Include="Hangfire.EntityFrameworkCore" Version="0.7.0" />
<PackageVersion Condition=" '$(sentry)' == 'true' OR '$(sentry)' == '' " Include="Sentry.AspNetCore" Version="5.11.2" />
Expand Down Expand Up @@ -74,6 +86,7 @@
<PackageVersion Condition=" '$(database)' == 'PostgreSQL' OR '$(database)' == '' " Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
<PackageVersion Condition=" '$(database)' == 'MySql' OR '$(database)' == '' " Include="Pomelo.EntityFrameworkCore.MySql" Version="9.0.0-preview.2.efcore.9.0.0" />
<PackageVersion Condition=" '$(filesStorage)' == 'AzureBlobStorage' OR '$(filesStorage)' == '' " Include="FluentStorage.Azure.Blobs" Version="5.3.0" />
<PackageVersion Condition=" '$(filesStorage)' == 'S3' OR '$(filesStorage)' == '' " Include="FluentStorage.AWS" Version="5.5.0" />
<PackageVersion Condition=" '$(appInsights)' == 'true' OR '$(appInsights)' == '' " Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.23.0" />
<PackageVersion Condition=" '$(pipeline)' == 'GitHub' OR '$(pipeline)' == '' " Include="GitHubActionsTestLogger" Version="2.4.1" />
<PackageVersion Condition=" '$(pipeline)' == 'Azure' " Include="AzurePipelines.TestLogger" Version="1.2.3" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
<PackageReference Include="Hangfire.EntityFrameworkCore" />
<PackageReference Include="HtmlSanitizer" />
<PackageReference Include="libphonenumber-csharp" />
<PackageReference Condition=" '$(appInsights)' == 'true' OR '$(appInsights)' == '' " Include="Microsoft.ApplicationInsights.AspNetCore" />
<PackageReference Include="Humanizer" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" />
Expand All @@ -35,6 +34,7 @@
<PackageReference Include="Magick.NET-Q16-AnyCPU" />
<PackageReference Include="FluentEmail.Smtp" />
<PackageReference Include="FluentStorage" />
<PackageReference Condition=" '$(filesStorage)' == 'S3' OR '$(filesStorage)' == '' " Include="FluentStorage.AWS" />
<PackageReference Condition=" '$(filesStorage)' == 'AzureBlobStorage' OR '$(filesStorage)' == '' " Include="FluentStorage.Azure.Blobs" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
Expand Down Expand Up @@ -85,7 +85,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Shared\Boilerplate.Shared.csproj" />
<ProjectReference Include="..\Boilerplate.Server.Shared\Boilerplate.Server.Shared.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,6 @@ namespace Microsoft.AspNetCore.Http;

internal static class HttpContextExtensions
{
internal static AppResponseCacheAttribute? GetResponseCacheAttribute(this HttpContext context)
{
var att = context.GetEndpoint()?.Metadata.OfType<AppResponseCacheAttribute>().FirstOrDefault();

if (att?.MaxAge == -1 && att?.SharedMaxAge == -1)
throw new InvalidOperationException("Invalid configuration: Both MaxAge and SharedMaxAge are unset. At least one of them must be specified in the ResponseCache attribute.");

return att;
}

//#if (api == "Integrated")
internal static bool IsBlazorPageContext(this HttpContext context)
{
return context.GetEndpoint()?.Metadata?.OfType<ComponentTypeMetadata>()?.Any() is true;
}
//#endif

/// <summary>
/// Validates the authentication status of an incoming HTTP request in an API endpoint that supports anonymous access.
/// If the request is unauthenticated (i.e., no valid user is associated with the context) but an Authorization header
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
using Boilerplate.Server.Api;
using Microsoft.Net.Http.Headers;
using Boilerplate.Server.Shared;

namespace Microsoft.AspNetCore.Http;

public static partial class HttpRequestExtensions
public static class HttpRequestExtensions
{
internal static Uri GetWebAppUrl(this HttpRequest req)
public static bool IsFromCDN(this HttpRequest request)
{
var settings = req.HttpContext.RequestServices.GetRequiredService<ServerApiSettings>();
return request.Headers.ContainsKey("CDN-Loop");
}

public static Uri GetWebAppUrl(this HttpRequest req)
{
var settings = req.HttpContext.RequestServices.GetRequiredService<ServerSharedSettings>();

var serverUrl = req.GetBaseUrl();

Expand All @@ -21,53 +25,4 @@ internal static Uri GetWebAppUrl(this HttpRequest req)

throw new BadRequestException($"Invalid origin {origin}");
}

internal static Uri GetUri(this HttpRequest request)
{
if (string.IsNullOrWhiteSpace(request.Scheme))
{
throw new ArgumentException("Http request Scheme is not specified");
}

return new Uri($"{request.Scheme}://{((!request.Host.HasValue) ? "UNKNOWN-HOST" : ((request.Host.Value.IndexOf(',') > 0) ? "MULTIPLE-HOST" : request.Host.Value))}{(request.PathBase.HasValue ? request.PathBase.Value : string.Empty)}{(request.Path.HasValue ? request.Path.Value : string.Empty)}{(request.QueryString.HasValue ? request.QueryString.Value : string.Empty)}");
}

/// <summary>
/// https://blog.elmah.io/how-to-get-base-url-in-asp-net-core/
/// </summary>
internal static Uri GetBaseUrl(this HttpRequest req)
{
var uriBuilder = new UriBuilder(req.Scheme, req.Host.Host, req.Host.Port ?? -1);
if (uriBuilder.Uri.IsDefaultPort)
{
uriBuilder.Port = -1;
}

return uriBuilder.Uri;
}

internal static bool IsFromCDN(this HttpRequest request)
{
return request.Headers.ContainsKey("CDN-Loop");
}

internal static bool IsLightHouseRequest(this HttpRequest request)
{
var agent = GetLoweredUserAgent(request);

if (agent.Contains("google")) return true;

if (agent.Contains("lighthouse")) return true;

return false;
}

private static string GetLoweredUserAgent(HttpRequest request)
{
var userAgent = request.Headers[HeaderNames.UserAgent].ToString();

if (string.IsNullOrEmpty(userAgent)) return string.Empty;

return userAgent.ToLowerInvariant();
}
}
Loading
Loading