diff --git a/templates/Coalesce.Vue.Template/TestLocal.ps1 b/templates/Coalesce.Vue.Template/TestLocal.ps1 index 1dbc62d9b..f0d738abe 100644 --- a/templates/Coalesce.Vue.Template/TestLocal.ps1 +++ b/templates/Coalesce.Vue.Template/TestLocal.ps1 @@ -1,23 +1,45 @@ $dir = $PSScriptRoot +$ErrorActionPreference = "Stop" +$PSNativeCommandUseErrorActionPreference = $false dotnet new uninstall IntelliTect.Coalesce.Vue.Template -Remove-Item -Path "$dir/IntelliTect.Coalesce.Vue.*.nupkg" +Remove-Item -Path "$dir/IntelliTect.Coalesce.Vue.Template.*.nupkg" -ErrorAction SilentlyContinue -dotnet pack -o $dir/. +$PSNativeCommandUseErrorActionPreference = $true -dotnet new install $(Get-ChildItem -Path "IntelliTect.Coalesce.Vue.*.nupkg").Name +dotnet pack $(Get-ChildItem -Path "$dir/*.csproj") -o $dir/. + +dotnet new install $(Get-ChildItem -Path "$dir/IntelliTect.Coalesce.Vue.Template.*.nupkg").FullName -rm $dir/Test.Template.Instance/* -Recurse dotnet new coalescevue --help -dotnet new coalescevue -o $dir/Test.Template.Instance - -Push-Location $dir/Test.Template.Instance/*.Web -try { - dotnet restore - dotnet coalesce - npm ci - npm run build - dotnet build -} finally { - Pop-Location + +$testCases = +# Nothing: +"", +# Everything: +"--Identity --MicrosoftAuth --GoogleAuth --UserPictures --AuditLogs --ExampleModel --DarkMode --TrackingBase --AppInsights --OpenAPI", +# Assorted partial variants: +"--Identity --UserPictures --TrackingBase" + +foreach ($testCase in $testCases) { + echo "----------------------" + echo "-------TEST CASE------" + echo "----------------------" + echo (!$testCase ? "" : $testCase); + echo "" + + rm $dir/Test.Template.Instance/* -Recurse + Invoke-Expression "dotnet new coalescevue -o $dir/Test.Template.Instance $testcase" + + Push-Location $dir/Test.Template.Instance/*.Web + try { + dotnet restore + dotnet coalesce + npm ci + npm run build + dotnet build + } + finally { + Pop-Location + } } \ No newline at end of file diff --git a/templates/Coalesce.Vue.Template/content/.template.config/template.json b/templates/Coalesce.Vue.Template/content/.template.config/template.json index d7e424735..08fbd3b7d 100644 --- a/templates/Coalesce.Vue.Template/content/.template.config/template.json +++ b/templates/Coalesce.Vue.Template/content/.template.config/template.json @@ -87,7 +87,6 @@ "**/SignIn.cshtml", "**/SignIn.cshtml.cs", "**/AppClaimTypes.cs", - "**/ClaimsPrincipalExtensions.cs", "**/ClaimsPrincipalFactory.cs", "**/Permission.cs", "**/User.cs", diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/ClaimsPrincipalExtensions.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/ClaimsPrincipalExtensions.cs index 20cd73d23..c586a1656 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/ClaimsPrincipalExtensions.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/ClaimsPrincipalExtensions.cs @@ -1,7 +1,8 @@ -namespace Coalesce.Starter.Vue.Data.Utilities; +namespace Coalesce.Starter.Vue.Data.Auth; public static class ClaimsPrincipalExtensions { +#if Identity public static string? GetUserId(this ClaimsPrincipal user) => user.FindFirstValue(AppClaimTypes.UserId); @@ -13,4 +14,13 @@ public static class ClaimsPrincipalExtensions public static bool Can(this ClaimsPrincipal user, params Permission[] permissions) => permissions.Any(p => user.HasClaim(AppClaimTypes.Permission, p.ToString())); + +#else + + public static string? GetUserId(this ClaimsPrincipal user) + => user.FindFirstValue(ClaimTypes.NameIdentifier); + + public static string? GetUserName(this ClaimsPrincipal user) + => user.FindFirstValue(ClaimTypes.Name); +#endif } \ No newline at end of file diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/Permission.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/Permission.cs index 140b40965..bb22a3aa1 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/Permission.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/Permission.cs @@ -7,6 +7,14 @@ /// public enum Permission { + // Note about usage of Permission values: + // The numeric values are stored in the database on `Role.Permissions`. + // The string value are stored in the user claims, + // issused by `ClaimsPrincipalFactory` and consumed by role-based security attributes with `nameof`. + + // Therefore, use caution and avoid editing existing roles. + // Always assign new roles the next highest value, never reusing old numbers. + [Display(Name = "Admin - General", Description = "Modify application configuration and other administrative functions excluding user/role management.")] Admin = 1, diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/SecurityService.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/SecurityService.cs index 34a1345df..5e1113047 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/SecurityService.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Auth/SecurityService.cs @@ -1,5 +1,4 @@ -using Coalesce.Starter.Vue.Data.Utilities; - + namespace Coalesce.Starter.Vue.Data.Auth; [Coalesce, Service] @@ -10,10 +9,10 @@ public UserInfo WhoAmI(ClaimsPrincipal user) { return new UserInfo { +#if Identity Id = user.GetUserId(), UserName = user.GetUserName(), -#if Identity Email = user.GetEmail(), FullName = user.FindFirstValue(AppClaimTypes.FullName), @@ -26,6 +25,9 @@ public UserInfo WhoAmI(ClaimsPrincipal user) .Where(c => c.Type == AppClaimTypes.Permission) .Select(c => c.Value) .ToList(), +#else + Id = user.FindFirstValue(ClaimTypes.NameIdentifier), + UserName = user.Identity?.Name, #endif }; } diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Coalesce/AuditOperationContext.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Coalesce/AuditOperationContext.cs index ed0d72659..3cd9bf0e3 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Coalesce/AuditOperationContext.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Coalesce/AuditOperationContext.cs @@ -1,6 +1,6 @@ -using Coalesce.Starter.Vue.Data.Models; +using Coalesce.Starter.Vue.Data.Auth; +using Coalesce.Starter.Vue.Data.Models; using IntelliTect.Coalesce.AuditLogging; -using IntelliTect.Coalesce.Utilities; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore.ChangeTracking; diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Models/TrackingBase.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Models/TrackingBase.cs index bd318afdb..b4d2838f0 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Models/TrackingBase.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Models/TrackingBase.cs @@ -1,4 +1,5 @@ -using IntelliTect.Coalesce.Utilities; +using Coalesce.Starter.Vue.Data.Auth; +using IntelliTect.Coalesce.Utilities; namespace Coalesce.Starter.Vue.Data.Models; diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Models/User.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Models/User.cs index 837131df0..ab69ea890 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Models/User.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Data/Models/User.cs @@ -1,3 +1,4 @@ +using Coalesce.Starter.Vue.Data.Auth; using Coalesce.Starter.Vue.Data.Coalesce; using IntelliTect.Coalesce.Helpers; using IntelliTect.Coalesce.Utilities; diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/AppInsightsTelemetryEnricher.cs b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/AppInsightsTelemetryEnricher.cs index 504949ce6..1402bb950 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/AppInsightsTelemetryEnricher.cs +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/AppInsightsTelemetryEnricher.cs @@ -1,4 +1,4 @@ -using Coalesce.Starter.Vue.Data.Utilities; +using Coalesce.Starter.Vue.Data.Auth; using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.DataContracts; using Microsoft.ApplicationInsights.Extensibility; diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/appsettings.json b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/appsettings.json index 4773d5611..7b2142cdd 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/appsettings.json +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/appsettings.json @@ -10,12 +10,14 @@ "Authentication": { //#if MicrosoftAuth "Microsoft": { + // Configuration instructions: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/social/microsoft-logins "ClientId": "", "ClientSecret": "" }, //#endif //#if GoogleAuth "Google": { + // Configuration instructions: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/social/google-logins "ClientId": "", "ClientSecret": "" }, diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/package-lock.json b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/package-lock.json index 57253ace2..c6b30866e 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/package-lock.json +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/package-lock.json @@ -10,8 +10,8 @@ "dependencies": { "@fortawesome/fontawesome-free": "^6.6.0", "@vueuse/core": "^11.0.3", - "coalesce-vue": "5.0.0-ci.20240830.2", - "coalesce-vue-vuetify3": "5.0.0-ci.20240830.2", + "coalesce-vue": "5.0.0-ci.20240905.3", + "coalesce-vue-vuetify3": "5.0.0-ci.20240905.3", "typeface-roboto": "1.1.13", "vue": "^3.5.0", "vue-router": "^4.4.3", @@ -1949,9 +1949,9 @@ } }, "node_modules/coalesce-vue": { - "version": "5.0.0-ci.20240830.2", - "resolved": "https://registry.npmjs.org/coalesce-vue/-/coalesce-vue-5.0.0-ci.20240830.2.tgz", - "integrity": "sha512-zetxt9IV1CbwK7LMTw233XrEqn/X7rMg0LZ118RfYozZWs2JuXTlbzzXaePlQOVECrg6oz9icThD1ebvzP3/qQ==", + "version": "5.0.0-ci.20240905.3", + "resolved": "https://registry.npmjs.org/coalesce-vue/-/coalesce-vue-5.0.0-ci.20240905.3.tgz", + "integrity": "sha512-/yvIvnV5VSoIq3R5kKkSkbg5ERhePA+OSQGbgn/LAwyZP11TPsDrfrar2qD4X9DpbCqD9uYWT9iFO+pAI7lQeA==", "dependencies": { "@types/lodash-es": "^4.17.3", "axios": "^1.3.4", @@ -1969,21 +1969,21 @@ } }, "node_modules/coalesce-vue-vuetify3": { - "version": "5.0.0-ci.20240830.2", - "resolved": "https://registry.npmjs.org/coalesce-vue-vuetify3/-/coalesce-vue-vuetify3-5.0.0-ci.20240830.2.tgz", - "integrity": "sha512-bSmoHDxvW29z+AQtJau8R69vvTvtB5BpAtLZmkGKCffoSraraEk8lVLlB9KrIiyH50myKuqH5BL5v+Cfrthi2A==", + "version": "5.0.0-ci.20240905.3", + "resolved": "https://registry.npmjs.org/coalesce-vue-vuetify3/-/coalesce-vue-vuetify3-5.0.0-ci.20240905.3.tgz", + "integrity": "sha512-s03t1y23B8uq5RzWwcpUHaCapFQhRpbskWbqIupJMTwmawh/JRqzQROyORorqaHQ17UR1DMaDgS/LUqJPP5Ulg==", "dependencies": { "date-fns": "^3.0.0", "date-fns-tz": "^3.0.0", "tslib": "^2.6.2" }, "optionalDependencies": { - "vue-router": "^4.1.0" + "vue-router": "^4.4.1" }, "peerDependencies": { - "coalesce-vue": "5.0.0-ci.20240830.2", + "coalesce-vue": "5.0.0-ci.20240905.3", "vue": "^3.4.0", - "vuetify": "^3.6.0" + "vuetify": "^3.7.1" } }, "node_modules/color-convert": { diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/package.json b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/package.json index 6ceaddf91..faaa819a0 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/package.json +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/package.json @@ -14,10 +14,9 @@ }, "dependencies": { "@fortawesome/fontawesome-free": "^6.6.0", - "@microsoft/applicationinsights-web": "^3.3.2", "@vueuse/core": "^11.0.3", - "coalesce-vue": "5.0.0-ci.20240830.2", - "coalesce-vue-vuetify3": "5.0.0-ci.20240830.2", + "coalesce-vue": "5.0.0-ci.20240905.3", + "coalesce-vue-vuetify3": "5.0.0-ci.20240905.3", "typeface-roboto": "1.1.13", "vue": "^3.5.0", "vue-router": "^4.4.3", diff --git a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/src/user-service.ts b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/src/user-service.ts index 764f376fc..0488cd9ef 100644 --- a/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/src/user-service.ts +++ b/templates/Coalesce.Vue.Template/content/Coalesce.Starter.Vue.Web/src/user-service.ts @@ -53,7 +53,7 @@ document.addEventListener( refreshUserInfo(); // Make useful properties available in vue