diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs index 9847a2b7a5..84e995f1fd 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs @@ -246,6 +246,17 @@ public class AngularSourceCodeAdder : ITransientDependency foreach (var folder in angularPathsInDownloadedSourceCode) { + var nodeModulesFolder = Path.Combine(folder, "node_modules"); + var vscodeFolder = Path.Combine(folder, ".vscode"); + if (Directory.Exists(nodeModulesFolder)) + { + Directory.Delete(nodeModulesFolder, true); + } + if (Directory.Exists(vscodeFolder)) + { + Directory.Delete(vscodeFolder, true); + } + var projectsInFolder = Directory.GetDirectories(folder); if (projectsInFolder.Length == 1 && Path.GetFileName(projectsInFolder[0]) == "projects") @@ -286,7 +297,7 @@ public class AngularSourceCodeAdder : ITransientDependency Directory.Move(projectInFolder, destDirName); } - if (!Directory.GetFiles(folder).Any() && !Directory.GetDirectories(folder).Any()) + if (!Directory.GetDirectories(folder).Any()) { Directory.Delete(folder, true); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs index 8aa17596a2..e6c21544b3 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs @@ -427,11 +427,6 @@ public class SolutionModuleAdder : ITransientDependency await PublishEventAsync(9, $"Adding angular source code"); - if (newTemplate) - { - MoveAngularFolderInNewTemplate(modulesFolderInSolution, moduleName); - } - await AngularSourceCodeAdder.AddFromModuleAsync(solutionFilePath, angularPath); } @@ -449,30 +444,6 @@ public class SolutionModuleAdder : ITransientDependency } } - private static void MoveAngularFolderInNewTemplate(string modulesFolderInSolution, string moduleName) - { - var moduleAngularFolder = Path.Combine(modulesFolderInSolution, moduleName, "angular"); - - if (!Directory.Exists(moduleAngularFolder)) - { - return; - } - - var files = Directory.GetFiles(moduleAngularFolder); - var folders = Directory.GetDirectories(moduleAngularFolder); - - Directory.CreateDirectory(Path.Combine(moduleAngularFolder, moduleName)); - - foreach (var file in files) - { - File.Move(file, Path.Combine(moduleAngularFolder, moduleName, Path.GetFileName(file))); - } - foreach (var folder in folders) - { - Directory.Move(folder, Path.Combine(moduleAngularFolder, moduleName, Path.GetFileName(folder))); - } - } - private async Task DownloadSourceCodesToSolutionFolder(ModuleWithMastersInfo module, string modulesFolderInSolution, string version = null, bool newTemplate = false, bool newProTemplate = false) diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Microsoft/AspNetCore/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Microsoft/AspNetCore/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs new file mode 100644 index 0000000000..8d26a17835 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Microsoft/AspNetCore/Extensions/DependencyInjection/AbpAspNetCoreServiceCollectionExtensions.cs @@ -0,0 +1,26 @@ +using System; +using Microsoft.Extensions.DependencyInjection; + +namespace Microsoft.AspNetCore.Extensions.DependencyInjection; + +public static class AbpAspNetCoreServiceCollectionExtensions +{ + public static IServiceCollection ForwardIdentityAuthenticationForBearer(this IServiceCollection services, string jwtBearerScheme = "Bearer") + { + services.ConfigureApplicationCookie(options => + { + options.ForwardDefaultSelector = ctx => + { + string authorization = ctx.Request.Headers.Authorization; + if (!authorization.IsNullOrWhiteSpace() && authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) + { + return jwtBearerScheme; + } + + return null; + }; + }); + + return services; + } +} diff --git a/npm/ng-packs/packages/theme-shared/src/lib/constants/validation.ts b/npm/ng-packs/packages/theme-shared/src/lib/constants/validation.ts index 463a7b01dc..65b759a21e 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/constants/validation.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/constants/validation.ts @@ -13,4 +13,8 @@ export const DEFAULT_VALIDATION_BLUEPRINTS = { range: 'AbpValidation::ThisFieldMustBeBetween{0}And{1}[{{ min }},{{ max }}]', required: 'AbpValidation::ThisFieldIsRequired.', url: 'AbpValidation::ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl', + passwordRequiresLower: 'AbpIdentity::Volo.Abp.Identity:PasswordRequiresLower', + passwordRequiresUpper: 'AbpIdentity::Volo.Abp.Identity:PasswordRequiresUpper', + passwordRequiresDigit: 'AbpIdentity::Volo.Abp.Identity:PasswordRequiresDigit', + passwordRequiresNonAlphanumeric: 'AbpIdentity::Volo.Abp.Identity:PasswordRequiresNonAlphanumeric', }; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts index ca6aa74124..4cb240e9ab 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/index.ts @@ -4,3 +4,4 @@ export * from './nav-item'; export * from './statistics'; export * from './toaster'; export * from './user-menu'; +export * from './validation'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/models/validation.ts b/npm/ng-packs/packages/theme-shared/src/lib/models/validation.ts new file mode 100644 index 0000000000..bcc53a34e7 --- /dev/null +++ b/npm/ng-packs/packages/theme-shared/src/lib/models/validation.ts @@ -0,0 +1 @@ +export type PasswordRule = 'small' | 'capital' | 'number' | 'special'; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/tests/validation-utils.spec.ts b/npm/ng-packs/packages/theme-shared/src/lib/tests/validation-utils.spec.ts index fe7577477c..435afb76e6 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/tests/validation-utils.spec.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/tests/validation-utils.spec.ts @@ -4,10 +4,11 @@ import { HttpClient } from '@angular/common/http'; import { Component, Injector } from '@angular/core'; import { Validators } from '@angular/forms'; import { createComponentFactory, Spectator } from '@ngneat/spectator/jest'; -import { validatePassword } from '@ngx-validate/core'; import { OAuthService } from 'angular-oauth2-oidc'; import { of } from 'rxjs'; -import { getPasswordValidators } from '../utils'; +import { getPasswordValidators, validatePassword } from '../utils'; +import { PasswordRule } from '../models/validation'; + @Component({ template: '', selector: 'abp-dummy' }) class DummyComponent {} @@ -47,8 +48,11 @@ describe('ValidationUtils', () => { configState.refreshAppState(); const validators = getPasswordValidators(spectator.inject(Injector)); + const passwordValidators = ['number', 'small', 'capital', 'special'].map( + (rule: PasswordRule) => validatePassword(rule), + ); const expectedValidators = [ - validatePassword(['number', 'small', 'capital', 'special']), + ...passwordValidators, Validators.minLength(6), Validators.maxLength(128), ]; diff --git a/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts b/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts index a9ec1d4270..cb201d224f 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/utils/validation-utils.ts @@ -1,7 +1,8 @@ import { ABP, ConfigStateService } from '@abp/ng.core'; import { Injector } from '@angular/core'; -import { ValidatorFn, Validators } from '@angular/forms'; -import { PasswordRules, validatePassword } from '@ngx-validate/core'; +import { AbstractControl, ValidatorFn, Validators } from '@angular/forms'; +import { normalizeDiacritics, PasswordRules } from '@ngx-validate/core'; +import { PasswordRule } from "../models/validation"; const { minLength, maxLength } = Validators; @@ -31,7 +32,8 @@ export function getPasswordValidators(injector: Injector): ValidatorFn[] { requiredLength = +getRule('RequiredLength'); } - return [validatePassword(passwordRulesArr), minLength(requiredLength), maxLength(128)]; + const passwordValidators = passwordRulesArr.map(rule => validatePassword(rule)); + return [...passwordValidators, minLength(requiredLength), maxLength(128)]; } function getRuleFn(injector: Injector) { @@ -43,3 +45,39 @@ function getRuleFn(injector: Injector) { return (passwordRules[`Abp.Identity.Password.${key}`] || '').toLowerCase(); }; } +const errorMessageMap = { + small: 'passwordRequiresLower', + capital: 'passwordRequiresUpper', + number: 'passwordRequiresDigit', + special: 'passwordRequiresNonAlphanumeric', +}; + +export function validatePassword( + shouldContain: PasswordRule +): ValidatorFn { + return (control: AbstractControl) => { + if (!control.value) return null; + + const value = normalizeDiacritics(control.value); + + const regexMap = { + small: /.*[a-z].*/, + capital: /.*[A-Z].*/, + number: /.*[0-9].*/, + special: /.*[^0-9a-zA-Z].*/, + }; + const regex = regexMap[shouldContain]; + + const isValid = regex.test(value); + + if (isValid) { + return null; + } + + const error = errorMessageMap[shouldContain]; + + return { + [error]: true, + }; + }; +} diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyProjectNameModule.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyProjectNameModule.cs index 8edcb2b6c6..0e5d86e4c7 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyProjectNameModule.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/MyProjectNameModule.cs @@ -1,5 +1,6 @@ using Blazorise.Bootstrap5; using Blazorise.Icons.FontAwesome; +using Microsoft.AspNetCore.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.OpenApi.Models; using MyCompanyName.MyProjectName.Data; @@ -137,7 +138,7 @@ public class MyProjectNameModule : AbpModule { context.Services.Replace(ServiceDescriptor.Singleton()); } - + ConfigureUrls(configuration); ConfigureBundles(); ConfigureAutoMapper(context); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameModule.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameModule.cs index 72203cef02..b9d407572b 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameModule.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameModule.cs @@ -1,5 +1,6 @@ using Blazorise.Bootstrap5; using Blazorise.Icons.FontAwesome; +using Microsoft.AspNetCore.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.OpenApi.Models; using MyCompanyName.MyProjectName.Data; @@ -133,7 +134,7 @@ public class MyProjectNameModule : AbpModule { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); - + if (hostingEnvironment.IsDevelopment()) { context.Services.Replace(ServiceDescriptor.Singleton()); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/MyProjectNameModule.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/MyProjectNameModule.cs index 62c14d681a..b9e6fe7590 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/MyProjectNameModule.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/MyProjectNameModule.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.OpenApi.Models; using MyCompanyName.MyProjectName.Data; @@ -120,7 +121,7 @@ public class MyProjectNameModule : AbpModule { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); - + if (hostingEnvironment.IsDevelopment()) { context.Services.Replace(ServiceDescriptor.Singleton()); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/MyProjectNameModule.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/MyProjectNameModule.cs index 4db85902c2..043d86a923 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/MyProjectNameModule.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/MyProjectNameModule.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.OpenApi.Models; using MyCompanyName.MyProjectName.Data; @@ -122,7 +123,7 @@ public class MyProjectNameModule : AbpModule { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); - + if (hostingEnvironment.IsDevelopment()) { context.Services.Replace(ServiceDescriptor.Singleton()); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/MyProjectNameModule.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/MyProjectNameModule.cs index 389597c523..5344e574bf 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/MyProjectNameModule.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/MyProjectNameModule.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.AspNetCore.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.OpenApi.Models; using MyCompanyName.MyProjectName.Data; using MyCompanyName.MyProjectName.Localization; @@ -126,7 +127,7 @@ public class MyProjectNameModule : AbpModule { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); - + if (hostingEnvironment.IsDevelopment()) { context.Services.Replace(ServiceDescriptor.Singleton()); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/MyProjectNameModule.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/MyProjectNameModule.cs index 976f91bf46..7fede74c7a 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/MyProjectNameModule.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/MyProjectNameModule.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.AspNetCore.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.OpenApi.Models; using MyCompanyName.MyProjectName.Data; using MyCompanyName.MyProjectName.Localization; @@ -127,7 +128,7 @@ public class MyProjectNameModule : AbpModule { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); - + if (hostingEnvironment.IsDevelopment()) { context.Services.Replace(ServiceDescriptor.Singleton()); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs index a3d2cf8057..2e251e86e9 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyProjectNameBlazorModule.cs @@ -2,6 +2,7 @@ using System.IO; using Blazorise.Bootstrap5; using Blazorise.Icons.FontAwesome; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Extensions.DependencyInjection; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs index b2e4aab2da..a981a370a8 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyProjectNameHttpApiHostModule.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs index 397f0a5db6..fb5079b2e9 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs @@ -1,6 +1,7 @@ using System; using System.IO; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Extensions.DependencyInjection; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs index 16d3ec947f..1c4acef254 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/MyProjectNameBlazorHostModule.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Blazorise.Bootstrap5; using Blazorise.Icons.FontAwesome; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting;