Browse Source

Merge branch 'dev' into blazor-binding-runtime

pull/19968/head
maliming 2 years ago
parent
commit
2f2fb26254
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  2. 73
      docs/en/cli/new-command-samples.md
  3. 84
      docs/en/deployment/forwarded-headers.md
  4. 1
      docs/en/deployment/index.md
  5. 19
      docs/en/studio/release-notes.md
  6. 2
      docs/en/studio/running-applications.md
  7. 1
      docs/en/studio/version-mapping.md
  8. 2
      latest-versions.json
  9. 3
      npm/ng-packs/packages/components/page/src/page.component.ts
  10. 8
      npm/ng-packs/packages/theme-shared/src/lib/services/abstract-menu.service.ts
  11. 9
      npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts

2
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json

@ -512,6 +512,7 @@
"QuotationTemplate.BankAccount": "Our bank account information can be found at {0}",
"Permission:Raffles": "Raffle",
"Permission:Draw": "Draw",
"Permission:ExportAttendeesAsExcel": "Export at attendees as Excel",
"Menu:Raffles": "Raffles",
"RaffleIsNotDrawable": "Raffle is not drawable",
"WinnerCountMustBeGreaterThanZero": "Winner count must be greater than zero",
@ -658,6 +659,7 @@
"DrawModal": "Private draw on the modal",
"SetAsDrawable": "Set as drawable",
"SetAsNoDrawable": "Set as non-drawable",
"SetAsCompleted": "Set as completed",
"RemoveAllWinners": "Remove all winners",
"EditWinners": "Edit winners",
"EditAttendees": "Edit attendees",

73
docs/en/cli/new-command-samples.md

@ -221,6 +221,79 @@ As seen below, ABP libraries are local project references.
</ItemGroup>
```
## Using Existing Configuration
If you want to programmaticaly create solutions, you can use an existing configuration instead of passing parameters to CLI one by one. ABP Studio keeps the solution creation history locally in `(UserProfile)\.abp\studio\solution-creation-history.json` file, there you can find the configurations of the solutions created in your machine.
### Using a Solution Id
In `*.abpsln` file of the solutions, there is an ID field that you can use to recreate a solution. To do this, pass the id to cli using `-shi or --solution-history-id` parameters.
```bash
abp new -shi dbb1afa9-190e-419a-842d-2780bb1bad1f
abp new -shi dbb1afa9-190e-419a-842d-2780bb1bad1f -o D:\test\Acme.BookStore
```
### Using a JSON Configuration File
You can also use a configuration file to create solutions. You need to use `-rcp or ready-config-path` parameters to do that.
```bash
abp new -rcp MyTests\config.json
abp new -rcp D:\MyTests\config.json
abp new -rcp D:\MyTests\config.json -o D:\test\Acme.BookStore
```
To prepare a config file, you can check the records in `solution-creation-history.json` file mentioned above. An example config file would look like that:
```json
{
"solutionName": {
"fullName": "Acme.BookStore",
"companyName": "Acme",
"projectName": "BookStore"
},
"pro": true,
"useOpenSourceTemplate": false,
"booksSample": false,
"databaseProvider": "ef",
"createInitialMigration": true,
"runDbMigrator": true,
"uiFramework": "angular",
"theme": "leptonx",
"themeStyle": "system",
"mobileFramework": "none",
"databaseManagementSystem": "sqlserver",
"databaseManagementSystemBuilderExtensionMethod": "UseSqlServer",
"connectionString": "Server=(LocalDb)\\\\MSSQLLocalDB;Database=BookStore;Trusted_Connection=True;TrustServerCertificate=true",
"mauiBlazorApplicationIdGuid": "d3499a09-f3d4-4bb7-9d58-4c7b1caee331",
"tiered": false,
"publicWebsite": false,
"cmskit": false,
"openIddictAdmin": true,
"languageManagement": true,
"textTemplateManagement": true,
"multiTenancy": true,
"auditLogging": false,
"gdpr": true,
"chat": false,
"fileManagement": false,
"socialLogins": true,
"includeTests": true,
"distributedEventBus": "none",
"publicRedis": false,
"separateTenantSchema": false,
"progressiveWebApp": false,
"runProgressiveWebAppSupport": false,
"runInstallLibs": false,
"runBundling": false,
"kubernetesConfiguration": true,
"templateName": "app"
}
```
## See Also
* [ABP CLI documentation](../cli/index.md)

84
docs/en/deployment/forwarded-headers.md

@ -0,0 +1,84 @@
# Forwarded Headers
Reverse proxies and load balancers play a crucial role in modern web application architectures. When an application is deployed behind these proxies and load balancers, several specific issues can arise. This document will discuss these issues in detail, explain how ASP.NET Core's forwarded headers middleware can address them, and provide a code example for configuring forwarded headers in an ABP application.
## Possible problem in a Reverse Proxy Environment
When requests pass through a reverse proxy or load balancer, the following common issues can occur:
### 1. Loss of Original Request Information
A reverse proxy or load balancer typically modifies the original HTTP request headers. For example, the proxy may replace the client's `X-Forwarded-For` header, or the `Host` header might be set to the proxy's address. This can result in the backend application being unable to directly access the client's IP address, the true hostname, and the protocol used.
### 2. HTTPS vs HTTP Protocol Confusion
When a request is forwarded by a proxy server, it is often upgraded to HTTPS to ensure secure transmission. The proxy server will send a header like `X-Forwarded-Proto` to indicate whether the original request was HTTP or HTTPS. If the backend application does not correctly handle this header, it may generate URLs with the wrong protocol.
### 3. Path Handling Issues
Since load balancers and proxies might modify or map the request URL paths differently, the backend application could encounter path inconsistencies. For example, a reverse proxy might forward a request from `/api` to `/myapp/api`. If the backend application is not correctly configured, path parsing errors may occur.
### 4. IP Address and Security
Reverse proxies might replace the original client IP address with their own, which can affect logging, authentication, and access control mechanisms. To retrieve the actual client IP address, the `X-Forwarded-For` header must be correctly parsed and trusted.
### 5. Load Balancer Impact
Load balancers might distribute requests to different backend servers using different algorithms. This can create session affinity problems. If session data is stored on a single server and the load balancer directs subsequent requests to different servers, session loss or inconsistency may occur.
## Forwarded Headers Middleware in ABP web application
To resolve the above issues, ASP.NET Core provides a built-in middleware, `ForwardedHeadersMiddleware`, which processes the headers forwarded by reverse proxies. This middleware helps the application recover the correct original request information, such as the client’s IP address, protocol, and host.
### Configuring `ForwardedHeadersMiddleware`
ASP.NET Core’s `ForwardedHeadersMiddleware` supports several HTTP headers:
- **X-Forwarded-For**: Contains the original client’s IP address.
- **X-Forwarded-Proto**: Indicates whether the original request was HTTP or HTTPS.
- **X-Forwarded-Host**: Contains the original host requested by the client.
- **X-Forwarded-Port**: Indicates the original port of the request.
To configure this middleware:
1. In the `ConfigureServices` method of your module, configure the `ForwardedHeadersOptions`:
```csharp
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
}
```
2. In the `OnApplicationInitialization` method of your module, add the middleware:
> Forwarded Headers Middleware should run before other middleware. This ordering ensures that the middleware relying on forwarded headers information can consume the header values for processing. Forwarded Headers Middleware can run after diagnostics and error handling, but it must be run before calling UseHsts:
```csharp
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
var env = context.GetEnvironment();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
else
{
app.UseErrorPage();
app.UseForwardedHeaders();
app.UseHsts();
}
// Other middleware configurations...
}
```
## References
- [ASP.NET Core Proxy and Load Balancer Configuration](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-9.0)

1
docs/en/deployment/index.md

@ -12,3 +12,4 @@ However, there are some topics that you should care about when you are deploying
* [Optimization for Production](./optimizing-production.md): Tips and suggestions for optimizing your application in production environments.
* [Deploying to a Clustered Environment](./clustered-environment.md): Explains how to configure your application when you want to run multiple instances of your application concurrently.
* [Deploying Distributed / Microservice Solutions](./distributed-microservice.md): Deployment notes for solutions consisting of multiple applications and/or services.
* [Forwarded Headers](./forwarded-headers): Explains how to configure the application to trust headers forwarded by reverse proxies and recover the original request information from the `X-Forwarded-For` and `X-Forwarded-Proto` headers.

19
docs/en/studio/release-notes.md

@ -2,6 +2,25 @@
This document contains **brief release notes** for each ABP Studio release. Release notes only include **major features** and **visible enhancements**. Therefore, they don't include all the development done in the related version.
## 0.9.11 (2024-11-21)
* Fixed the extension loading problem occured in v0.9.9 & v0.9.10.
## 0.9.10 (2024-11-21)
> Recommended to use v0.9.11+ for .NET 9.
* Added shortcut for Build & Start operation (CTRL + Click)
* Fixed extension loading loop problem in v0.9.9
* Fixed MAUI template for android
## 0.9.9 (2024-11-21)
> Recommended to use v0.9.11+ for .NET 9.
* Upgraded templates to .NET 9
* Fixed blazor wasm bundle problem in microservice template
## 0.9.8 (2024-11-20)
* Upgraded templates to version `8.3.4`

2
docs/en/studio/running-applications.md

@ -187,6 +187,8 @@ We have several options in C# applications. Those options are `Start`(If the app
> When *Watch* is enable you should see an *eye* icon next to the application name.
> Hint: Performing CTRL+Click on the start icon left to a stopped C# application equals to `Build & Start` command. Same applies for folders.
![csharp-application-context-menu-run-connection](images/solution-runner/csharp-application-context-menu-run-connection.png)
### Build

1
docs/en/studio/version-mapping.md

@ -4,6 +4,7 @@ This document provides a general overview of the relationship between various ve
| **ABP Studio Version** | **ABP Version of Startup Template** |
|------------------------|---------------------------|
| 0.9.9 to 0.9.11 | 9.0.0 |
| 0.9.8 | 8.3.4 |
| 0.9.5 to 0.9.7 | 8.3.3 |
| 0.9.2 to 0.9.4 | 8.3.2 |

2
latest-versions.json

@ -1,6 +1,6 @@
[
{
"version": "8.3.4",
"version": "9.0.0",
"releaseDate": "",
"type": "stable",
"message": ""

3
npm/ng-packs/packages/components/page/src/page.component.ts

@ -45,7 +45,8 @@ export class PageComponent {
this.breadcrumb ||
this.customTitle ||
this.customBreadcrumb ||
this.customToolbar
this.customToolbar ||
this.pageParts
);
}
}

8
npm/ng-packs/packages/theme-shared/src/lib/services/abstract-menu.service.ts

@ -1,12 +1,12 @@
import { BehaviorSubject, Observable } from 'rxjs';
import { NavItem } from '../models/nav-item';
import { inject, Type } from '@angular/core';
import { SORT_COMPARE_FUNC } from '@abp/ng.core';
import { SORT_COMPARE_FUNC, SortableItem } from '@abp/ng.core';
export abstract class AbstractMenuService<T extends NavItem> {
protected abstract baseClass: Type<any>;
protected readonly sortFn = inject(SORT_COMPARE_FUNC);
protected readonly sortFn: (a: SortableItem, b: SortableItem) => number;
protected _items$ = new BehaviorSubject<T[]>([]);
@ -18,6 +18,10 @@ export abstract class AbstractMenuService<T extends NavItem> {
return this._items$.asObservable();
}
constructor() {
this.sortFn = inject(SORT_COMPARE_FUNC);
}
addItems(newItems: T[]) {
const items = [...this.items];
newItems.forEach(item => {

9
npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts

@ -4,7 +4,7 @@ import {
PROJECTION_STRATEGY,
Strict,
} from '@abp/ng.core';
import { ComponentRef, Injectable } from '@angular/core';
import { ComponentRef, inject, Injectable } from '@angular/core';
import { ReplaySubject } from 'rxjs';
import { ToastContainerComponent } from '../components/toast-container/toast-container.component';
import { Toaster } from '../models';
@ -20,8 +20,7 @@ export class ToasterService implements ToasterContract {
private toasts = [] as Toaster.Toast[];
private containerComponentRef!: ComponentRef<ToastContainerComponent>;
constructor(private contentProjectionService: ContentProjectionService) {}
private contentProjectionService: ContentProjectionService;
private setContainer() {
this.containerComponentRef = this.contentProjectionService.projectContent(
@ -34,6 +33,10 @@ export class ToasterService implements ToasterContract {
this.containerComponentRef.changeDetectorRef.detectChanges();
}
constructor() {
this.contentProjectionService = inject(ContentProjectionService);
}
/**
* Creates an info toast with given parameters.
* @param message Content of the toast

Loading…
Cancel
Save