"MyOrganizations_Detail_PaymentProviderInfo":"If you have purchased your license through <i>{0}</i> gateway, it sends the PDF invoice to your email address, see <a href=\"{1}\" target=\"_blank\">{0} invoicing.</a>",
"MyOrganizations_Detail_PayUInfo":"If you have purchased through the <i>PayU</i> gateway, click the \"Request Invoice\" button and fill in the billing information.",
"MyOrganizations_Detail_PayUInfo":"If you have purchased through the <i>Iyzico</i> gateway, click the \"Request Invoice\" button and fill in the billing information.",
"MyOrganizations_Detail_ConclusionInfo":"Your invoice request will be concluded within {0} business days.",
"ExtendYourLicense":"Extend your <span class=\"text-primary\">{0}</span> license",
"Continue":"Continue",
@ -1001,19 +1001,19 @@
"ABPSOLUTION":"ABP SOLUTION",
"CreatingAnEmptySolution_ABPSOLUTION_Description":"ABP provides a well-architected, layered and production-ready <a href=\"https://docs.abp.io/en/abp/latest/Startup-Templates/Application\" target=\"_blank\">startup solution</a> based on the <a href=\"https://docs.abp.io/en/abp/latest/Domain-Driven-Design\" target=\"_blank\">Domain Driven Design</a> principles. The solution also includes a pre-configured unit and integration <a href=\"https://docs.abp.io/en/abp/latest/Testing\" target=\"_blank\">test</a> projects for each layer.",
"CommonLibraries":"Common Libraries",
"CommonLibraries_THEPROBLEM_Description":"Which libraries should you use to implement common requirements? The software development ecosystem is highly dynamic and it is hard to follow the latest tools, libraries, trends and approaches.",
"CommonLibraries_ABPSOLUTION_Description":"ABP pre-integrates the popular, mature and up-to-date libraries into the solution. You don't spend time integrating them and talking to each other. They properly work out of the box.",
"CommonLibraries_THEPROBLEM_Description":"Which libraries should you use to implement common requirements? The software development ecosystem is highly dynamic, making it challenging to keep up with the latest tools, libraries, trends, and approaches.",
"CommonLibraries_ABPSOLUTION_Description":"ABP pre-integrates popular, mature, and up-to-date libraries into the solution. You don't need to spend time integrating them or making them communicate with each other. They work properly out of the box.",
"UITheme&Layout":"UI Theme & Layout",
"UITheme&Layout_THEPROBLEM_Description":"When it comes to the UI, there are a lot of challenges, including preparing a foundation to create a responsive, modern and flexible UI kit with a consistent look & feel and tons of features (like left/top navigation menu, header, toolbar, footer, widgets and so.).",
"UITheme&Layout_THEPROBLEM_Description2":"Even if you buy a pre-built theme, integrating it into your solution may take days of development. Upgrading such a theme is another problem. Most of the time, the theme's HTML/CSS structure is mixed with your UI code, and it is not easy to upgrade or change the theme later.",
"UITheme&Layout_ABPSOLUTION_Description":"ABP Framework provides a <a href=\"https://docs.abp.io/en/abp/latest/UI/AspNetCore/Theming\" target=\"_blank\"> theming</a> system that makes your UI code independent from the theme. Themes are isolated, and they are NuGet/NPM packages. Installing or upgrading a theme is just a minute. While you can build your theme (or integrate an existing theme), ABP Commercial offers professional and modern <a href=\"/themes\">themes</a>.",
"UITheme&Layout_ABPSOLUTION_Description2":"There are also UI component providers (like Telerik and DevExpress). But they only provide individual components. You are responsible for creating your own layout system. You can use such libraries in your ABP-based solutions just like in any other project.",
"UITheme&Layout_THEPROBLEM_Description":"When addressing UI concerns, a range of challenges surfaces. These include establishing the groundwork for a responsive, contemporary, and adaptable UI kit with a consistent appearance and a host of features like navigation menus, headers, toolbars, footers, widgets, and more.",
"UITheme&Layout_THEPROBLEM_Description2":"Even if you opt for a pre-designed theme, seamlessly integrating it into your project could demand days of development. An additional hurdle lies in upgrading such themes. Frequently, the theme's HTML/CSS structure becomes intertwined with your UI code, rendering future theme changes or upgrades intricate tasks. This interweaving of code and design complicates the flexibility of making adjustments down the line.",
"UITheme&Layout_ABPSOLUTION_Description":"ABP Framework offers a distinctive theming system that liberates your UI code from theme constraints. Themes exist in isolation, packaged as NuGet or NPM packages, making theme installation or upgrades a matter of minutes. While you retain the option to develop your custom theme or integrate an existing one, ABP Commercial presents a collection of polished and contemporary themes.",
"UITheme&Layout_ABPSOLUTION_Description2":"Additionally, there are UI component providers like Telerik and DevExpress. However, these providers primarily furnish individual components, placing the onus on you to establish your layout system. When working within ABP-based projects, you can seamlessly incorporate these libraries, similar to how you would in any other project.",
"TestInfrastructure":"Test Infrastructure",
"TestInfrastructure_THEPROBLEM_Description":"Preparing a robust test environment takes time. You need to setup test projects in your solution, select the tools, mock the services and database, create the required base classes and utility services to reduce repeating code in the tests and so on.",
"TestInfrastructure_ABPSOLUTION_Description":"ABP Startup Templates comes with the test projects already configured for you, and you can immediately write your first unit or integration test code on day 1.",
"TestInfrastructure_THEPROBLEM_Description":"Establishing a robust testing environment is a time-consuming endeavor. It involves setting up dedicated test projects within your solution, carefully selecting the necessary tools, creating service and database mocks, crafting essential base classes and utility services to minimize redundant code across tests, and addressing various related tasks.",
"TestInfrastructure_ABPSOLUTION_Description":"ABP Startup Templates arrive pre-equipped with configured test projects, streamlining the process for you. This means that from day one, you can readily commence writing your initial unit or integration test code without delay.",
"CodingStandards&Training_THEPROBLEM_Description":"Once you create the development-ready solution, you typically need to train the developers to explain the system and develop it with the same conventions in a standard and consistent way. Even if you train the developers, it is hard to prepare and maintain your documentation. Over time, every developer will write the code differently, and coding standards will begin to diverge.",
"CodingStandards&Training_ABPSOLUTION_Description":"ABP solution is already well-defined and well-documented. <a href=\"https://docs.abp.io/en/abp/latest/Tutorials/Part-1\" target=\"_blank\">Tutorials</a> and <a href=\"https://docs.abp.io/en/abp/latest/Best-Practices/Index\" target=\"_blank\">best practice guides</a> clearly explain how to make development on an ABP project.",
"CodingStandards&Training_THEPROBLEM_Description":"After you've set up the solution for development, you usually have to teach the developers how the system works and how to build it using the same agreed-upon methods. Even if you give them training, keeping the documentation up-to-date can be difficult. As time goes on, each developer might write code in their own way, causing the rules for writing code to become different from each other.",
"CodingStandards&Training_ABPSOLUTION_Description":"The ABP solution is already neatly organized and has clear explanations. Step-by-step tutorials and guides show you exactly how to work on an ABP project.",
"KeepingYourSolutionUpToDate":"Keeping Your Solution Up to Date",
"KeepingYourSolutionUpToDate_THEPROBLEM_Description":"After you start your development, you must keep track of the new versions of the libraries you use for upgrades & patches.",
"KeepingYourSolutionUpToDate_ABPSOLUTION_Description":"We regularly update all packages to the latest versions and test them before the stable release. When you update the ABP Framework, all its dependencies are upgraded to edge technology.",
@ -1073,6 +1073,8 @@
"ABPCommunity_Description2":"It is easy to share code or even re-usable libraries between ABP developers. A code snippet that works for you will also work for others. There are a lot of samples and tutorials that you can directly implement for your application.",
"ABPCommunity_Description3":"When you hire a developer who worked before with the ABP architecture will immediately understand your solution and start development in a very short time.",
"WhyAbpIo_Page_Title":"Why ABP.IO Platform?",
"AbpStudio_Page_Title":"ABP Studio"
"AbpStudio_Page_Title":"ABP Studio",
"CampaignInfo":"Buy a new license or renew your existing license and <span class=\"text-white\">get an additional 2 months</span> at no additional cost! This offer is valid for all license plans. Ensure you take advantage of this limited-time promotion to expand your access to premium features and upgrades.",
@ -153,3 +153,38 @@ public override void OnApplicationInitialization(ApplicationInitializationContex
```
> Do not forget to set `OAuthClientId` and `OAuthClientSecret`.
## Using Swagger with OIDC
You may also want to configure swagger using **OpenIdConnect** instead of OAUTH. This is especially useful when you need to configure different metadata address than the issuer in cases such as when you deploy your application to kubernetes cluster or docker. In these cases, metadata address will be used in sign-in process to reach the valid authentication server discovery endpoint over the internet and use the internal network to validate the obtained token.
To do that, we need to use `AddAbpSwaggerGenWithOidc` extension to configure Swagger with OAuth issuer and scopes in `ConfigureServices` method of our module:
The `flows` is a list of default oidc flows that is supported by the oidc-provider (authserver). You can see the default supported flows below:
- `AbpSwaggerOidcFlows.AuthorizationCode`: The `"authorization_code"` flow is the **default and suggested** flow. **Doesn't require a client secret** when even there is a field for it.
- `AbpSwaggerOidcFlows.Implicit`: The deprecated `"implicit"` flow that was used for javascript applications.
- `AbpSwaggerOidcFlows.Password`: The legacy `password` flow which is also known as Resource Ownder Password flow. You need to provide a user name, password and client secret for it.
- `AbpSwaggerOidcFlows.ClientCredentials`: The `"client_credentials"` flow that is used for server to server interactions.
You can define one or many flows which will be shown in the Authorize modal. You can set it **null which will use the default "authorization_code"** flow.
The `discoveryEndpoint` is the reachable openid-provider endpoint for the `.well-known/openid-configuration`. You can set it to **null which will use default AuthServer:Authority** appsettings configuration. If you are deploying your applications to a kubernetes cluster or docker swarm, you should to set the `discoveryEndpoint` as real DNS that should be reachable over the internet.
> If are having problems with seeing the authorization modal, check the browser console logs and make sure you have a correct and reachable `discoveryEndpoint`
AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName") }
options.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName") };
});
```
**Important**: `UseHangfireDashboard` should be called after the authentication and authorization middlewares in your `Startup` class (probably at the last line). Otherwise,
**Important**: `UseAbpHangfireDashboard` should be called after the authentication and authorization middlewares in your `Startup` class (probably at the last line). Otherwise,
> **IMPORTANT**: Outbox sending service uses distributed locks to ensure only a single instance of your application consumes the outbox queue concurrently. Distributed locking key should be unique per database. The `config` object (in the preceding code example) has a `DatabaseName` property, which is used in the distributed lock key to ensure the uniqueness. `DatabaseName` is automatically set by the `UseDbContext` method, getting the database name from the `ConnectionStringName` attribute of the `YourDbContext` class. So, if you have multiple databases in your system, ensure that you use the same connection string name for the same database, but different connection string names for different databases. If you can't ensure that, you can manually set `config.DatabaseName` (after the `UseDbContext` line) to ensure that uniqueness.
### Enabling event inbox
Open your `DbContext` class (EF Core or MongoDB), implement the `IHasEventInbox` interface. You should end up by adding a `DbSet` property into your `DbContext` class:
**IMPORTANT**: Inbox processing service uses distributed locks to ensure only a single instance of your application consumes the inbox queue concurrently. Distributed locking key should be unique per database. The `config` object (in the preceding code example) has a `DatabaseName` property, which is used in the distributed lock key to ensure the uniqueness. `DatabaseName` is automatically set by the `UseDbContext` method, getting the database name from the `ConnectionStringName` attribute of the `YourDbContext` class. So, if you have multiple databases in your system, ensure that you use the same connection string name for the same database, but different connection string names for different databases. If you can't ensure that, you can manually set `config.DatabaseName` (after the `UseDbContext` line) to ensure that uniqueness.
### Additional Configuration
> The default configuration will be enough for most cases. However, there are some options you may want to set for outbox and inbox.
@ -525,6 +529,7 @@ Here, the following properties are available on the `config` object:
* `IsSendingEnabled` (default: `true`): You can set to `false` to disable sending outbox events to the actual event bus. If you disable this, events can still be added to outbox, but not sent. This can be helpful if you have multiple applications (or application instances) writing to outbox, but use one of them to send the events.
* `Selector`: A predicate to filter the event (ETO) types to be used for this configuration. Should return `true` to select the event. It selects all the events by default. This is especially useful if you want to ignore some ETO types from the outbox, or want to define named outbox configurations and group events within these configurations. See the *Named Configurations* section.
* `ImplementationType`: Type of the class that implements the database operations for the outbox. This is normally set when you call `UseDbContext` as shown before. See *Implementing a Custom Outbox/Inbox Database Provider* section for advanced usages.
* `DatabaseName`: Unique database name for the database that is used for this outbox configuration. See the **IMPORTANT** paragraph at the end of the *Enabling event outbox* section.
#### Inbox configuration
@ -546,6 +551,7 @@ Here, the following properties are available on the `config` object:
* `EventSelector`: A predicate to filter the event (ETO) types to be used for this configuration. This is especially useful if you want to ignore some ETO types from the inbox, or want to define named inbox configurations and group events within these configurations. See the *Named Configurations* section.
* `HandlerSelector`: A predicate to filter the event handled types (classes implementing the `IDistributedEventHandler<TEvent>` interface) to be used for this configuration. This is especially useful if you want to ignore some event handler types from inbox processing, or want to define named inbox configurations and group event handlers within these configurations. See the *Named Configurations* section.
* `ImplementationType`: Type of the class that implements the database operations for the inbox. This is normally set when you call `UseDbContext` as shown before. See *Implementing a Custom Outbox/Inbox Database Provider* section for advanced usages.
* `DatabaseName`: Unique database name for the database that is used for this outbox configuration. See the **IMPORTANT** paragraph at the end of the *Enabling event inbox* section.
@ -471,7 +471,24 @@ In **Blazor wasm** applications, add `options.ProviderOptions.DefaultScopes.Add(
In **Angular** applications, add `offline_access` to **oAuthConfig** scopes in *environment.ts* file. (Angular applications already have this configuration).
## About localization
We don't localize any error messages in the OpenIddict module, Because the OAuth 2.0 specification restricts the charset you're allowed to use for the error and error_description parameters:
> A.7. "error" Syntax
> The "error" element is defined in Sections 4.1.2.1, 4.2.2.1, 5.2, 7.2, and 8.5:
```
error = 1*NQSCHAR
```
> A.8. "error_description" Syntax
>T he "error_description" element is defined in Sections 4.1.2.1, 4.2.2.1, 5.2, and 7.2:
thrownewAbpException("No sorting specified but this query requires sorting. Override the ApplyDefaultSorting method for your application service derived from AbstractKeyReadOnlyAppService!");
thrownewAbpException("No sorting specified but this query requires sorting. Override the ApplySorting or the ApplyDefaultSorting method for your application service derived from AbstractKeyReadOnlyAppService!");