Activities of "kfrancis@clinicalsupportsystems.com"

Shared now with shiwei.liang@volosoft.com

I imagine there would need to be one of these per each (light, dark, dim)?

I've sent the invite, sorry - I thought it was an invite link, but I had to invite that email directly - if that won't work just let me know (reply to email) and I'll send a direct invite.

To provide context for the task at hand, we are working on a project that utilizes the LeptonX theme and incorporates Telerik's Kendo UI components. While LeptonX offers a great UI experience, the Telerik Kendo components are not visually aligned with this theme out-of-the-box. To bridge this gap, we are looking to use Telerik's ThemeBuilder application. ThemeBuilder is designed to customize the visual appearance of Telerik and Kendo UI web components. It features an intuitive UI, allowing us to manipulate colors, border-radius, typography, and other appearance-related properties. The end goal is to generate a theme as an npm package containing ready-to-use Sass and CSS that integrates seamlessly with the LeptonX theme.

The challenge we're facing is twofold:

  • The customization in ThemeBuilder needs to be precisely done so that the resulting Kendo UI elements blend seamlessly into the LeptonX environment.
  • After generating the customized theme package, it has to be integrated into our existing project architecture that utilizes abp.io. This includes resolving any conflicts and ensuring that the custom theme does not break or interfere with existing styles or functionalities.

Our aim is to ensure that the Kendo UI components, once styled through ThemeBuilder, work cohesively within the LeptonX theme without causing any visual or functional discrepancies. We require expert assistance from abp.io staff for guidance on how best to integrate the npm package generated by ThemeBuilder into our abp.io-based application, including any nuances or best practices that we should be aware of. This integration will likely involve configuration changes in abp.io as well as adjustments to our build process to accommodate the new Sass and CSS files.

Your expertise in abp.io will be crucial for the successful completion of this task, particularly in ensuring a smooth integration that is maintainable and updateable in the long term.

Answer

Trying to create the sample issue here: https://github.com/kfrancis/net8-maui-autofac-repro

MauiApp1 is just a simple maui app, that was net7.0 with autofac (not abp) and was working. Then upgraded to net8 preview 6 and it still works.

MauiApp2 is the same, but I suspect the issue comes into play with abp autofac so I'm trying to prepare a simple example of that.

Just in case others find this thread, the issue for us was that we still had some packages from before our Lepton to LeptonX migration - Volo.Abp.LeptonTheme.*. Once we removed those six packages, it started working normally.

No change.

Here's the web module def:

[DependsOn(
    typeof(CabMDHttpApiModule),
    typeof(CabMDHttpApiClientModule),
    typeof(AbpAspNetCoreAuthenticationOpenIdConnectModule),
    typeof(AbpAspNetCoreMvcClientModule),
    typeof(AbpAutofacModule),
    typeof(AbpCachingStackExchangeRedisModule),
    typeof(AbpFeatureManagementWebModule),
    typeof(AbpAccountAdminWebModule),
    typeof(AbpHttpClientIdentityModelWebModule),
    typeof(AbpIdentityWebModule),
    typeof(AbpAuditLoggingWebModule),
    typeof(AbpAspNetCoreMvcUiLeptonXThemeModule),
    typeof(SaasHostWebModule),
    typeof(AbpOpenIddictProWebModule),
    typeof(LanguageManagementWebModule),
    typeof(TextTemplateManagementWebModule),
    typeof(AbpSwashbuckleModule),
    typeof(AbpAspNetCoreSerilogModule),
    typeof(AbpPaymentPayuWebModule),
    typeof(AbpPaymentTwoCheckoutWebModule),
    typeof(AbpPaymentWebModule),
    typeof(FileManagementWebModule),
    typeof(DocsWebModule),
    typeof(CabMDReportingModule),
    typeof(CmsKitProWebModule),
    typeof(AbpBlobStoringModule),
    typeof(AbpTextTemplatingScribanModule)
)]
public class CabMDWebModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var hostingEnvironment = context.Services.GetHostingEnvironment();
        var configuration = context.Services.GetConfiguration();

        ConfigureBundles();
        ConfigurePages();
        ConfigureCache();
        ConfigureRedis(context, configuration, hostingEnvironment);
        ConfigureUrls(configuration);
        ConfigureAuthentication(context, configuration);
        ConfigureAutoMapper();
        ConfigureVirtualFileSystem(hostingEnvironment);
        ConfigureNavigationServices(configuration);
        ConfigureSwaggerServices(context.Services);
        ConfigureMultiTenancy();
        ConfigureBackgroundJobs(context, configuration);
        ConfigurePayment();
        ConfigureKendo(context.Services);
        ConfigureReporting(context, configuration);
        ConfigurePwnedPasswords(context.Services);
        ConfigureMiniProfiler(configuration, context.Services);
        ConfigureJsonSerialization();
        ConfigureBlobStorage();
        ConfigureLayoutChanges(configuration);
        //ConfigureHealthChecks(context, configuration);
    }

    public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var app = context.GetApplicationBuilder();
        var env = context.GetEnvironment();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseAbpRequestLocalization();

        if (!env.IsDevelopment())
        {
            app.UseErrorPage();
        }
        app.UseCors("TelerikReportingCorsPolicy");

        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthentication();

        if (MultiTenancyConsts.IsEnabled)
        {
            app.UseMultiTenancy();
        }

        app.UseAuthorization();
        if (bool.Parse(context.GetConfiguration()["App:EnableMiniProfiler"]))
        {
            app.UseMiniProfiler();
        }

        if (BackgroundJobConsts.IsEnabled)
        {
            app.UseHangfireDashboard("/hangfire", new DashboardOptions
            {
                AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }
            });
        }

        app.UseSwagger();
        app.UseAbpSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "CabMD API");
        });
        app.UseAuditing();
        app.UseAbpSerilogEnrichers();
        app.UseConfiguredEndpoints();
    }

    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
        {
            options.AddAssemblyResource(
                typeof(CabMDResource),
                typeof(CabMDDomainSharedModule).Assembly,
                typeof(CabMDApplicationContractsModule).Assembly,
                typeof(CabMDWebModule).Assembly
            );
        });
    }

    private static void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("Cookies", options =>
            {
                options.ExpireTimeSpan = TimeSpan.FromDays(365);
            })
            .AddAbpOpenIdConnect("oidc", options =>
            {
                options.Authority = configuration["AuthServer:Authority"];
                options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]); ;
                options.ResponseType = OpenIdConnectResponseType.CodeIdToken;

                options.ClientId = configuration["AuthServer:ClientId"];
                options.ClientSecret = configuration["AuthServer:ClientSecret"];

                options.UsePkce = true; // Add this line
                options.SaveTokens = true;
                options.GetClaimsFromUserInfoEndpoint = true;

                options.Scope.Add("roles");
                options.Scope.Add("email");
                options.Scope.Add("phone");
                options.Scope.Add("CabMD");
            });
    }

    private static void ConfigureHealthChecks(ServiceConfigurationContext context, IConfiguration configuration)
    {
        if (configuration.GetValue("HealthChecks:HealthChecksEnabled", false))
        {
            context.Services.AddCabHealthChecks(configuration.GetConnectionString("Default"));
        }
    }

    private static void ConfigureKendo(IServiceCollection services)
    {
        services.AddKendo();
    }

    private static void ConfigureMiniProfiler(IConfiguration configuration, IServiceCollection services)
    {
        if (configuration.GetValue("App:EnableMiniProfiler", false))
        {
            services.AddMiniProfiler(options =>
            {
                options.RouteBasePath = "/mp";
                options.SqlFormatter = new StackExchange.Profiling.SqlFormatters.VerboseSqlServerFormatter();
                options.IgnoredPaths.Add("/elmah");
                options.IgnoredPaths.Add(".less");
                options.TrackConnectionOpenClose = false;
                options.PopupShowTimeWithChildren = true;
                options.Storage = new RedisStorage(configuration["Redis:Configuration"]);
            }).AddEntityFramework();
        }
    }

    /// <summary>
    /// Adds the PwnedPasswords client in DI so we can check during user registration
    /// </summary>
    /// <param name="services"></param>
    private static void ConfigurePwnedPasswords(IServiceCollection services)
    {
        // see: https://blog.elmah.io/avoid-password-reuse-with-pwned-passwords-and-asp-net-core/

        services.AddPwnedPasswordHttpClient(minimumFrequencyToConsiderPwned: 1)
            .AddTransientHttpErrorPolicy(p => p.RetryAsync(3))
            .AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(2)));
    }

    private static void ConfigureRedis(
        ServiceConfigurationContext context,
        IConfiguration configuration,
        IWebHostEnvironment hostingEnvironment)
    {
        var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("CabMD");
        if (!hostingEnvironment.IsDevelopment())
        {
            var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
            dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "CabMD-Protection-Keys");
        }

        context.Services.AddSingleton<IDistributedLockProvider>(sp =>
        {
            var connection = ConnectionMultiplexer
                .Connect(configuration["Redis:Configuration"]);
            return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
        });
    }

    private static void ConfigureReporting(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.Configure<IISServerOptions>(options => { options.AllowSynchronousIO = true; });
        context.Services.AddScoped<IReportSourceResolver, CabMDReportSourceResolver>();
        context.Services.AddSingleton<IReportServiceConfiguration>(sp =>
            new ReportServiceConfiguration
            {
                ReportingEngineConfiguration = configuration,
                HostAppId = "ReportingCore3App",
                Storage = new FileStorage(),
                ReportSourceResolver = sp.GetRequiredService<IReportSourceResolver>()
            });
        context.Services.AddCors(o => o.AddPolicy("TelerikReportingCorsPolicy", builder =>
        {
            builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader();
        }));
        context.Services.AddControllers().AddNewtonsoftJson(opt =>
        {
            opt.SerializerSettings.ContractResolver = new ApiHeaderJsonContractResolver(new ApiHeaderJsonNamingStrategyOptions
            {
                DefaultStrategy = new PascalCaseNamingStrategy(),
                HeaderName = "json-naming-strategy",
                HttpContextAccessorProvider = context.Services.BuildServiceProvider().GetService<IHttpContextAccessor>,
                NamingStrategies = new Dictionary<string, NamingStrategy>
                {
                    {"camelcase", new CamelCaseNamingStrategy() },
                    {"snakecase", new SnakeCaseNamingStrategy() },
                    {"pascalcase", new PascalCaseNamingStrategy() }
                }
            }, context.Services.BuildServiceProvider().GetService<IMemoryCache>);
        }).AddJsonOptions(options =>
        {
        });
        context.Services.AddRazorPages().AddNewtonsoftJson();
    }

    private static void ConfigureSwaggerServices(IServiceCollection services)
    {
        services.AddSwaggerGen(
            options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo { Title = "CabMD API", Version = "v1" });
                options.DocInclusionPredicate((docName, description) => true);
                options.CustomSchemaIds(type => type.FullName);
            }
        );
    }

    private void ConfigureAutoMapper()
    {
        Configure<AbpAutoMapperOptions>(options =>
        {
            options.AddMaps<CabMDWebModule>();
        });
    }

    private void ConfigureBackgroundJobs(ServiceConfigurationContext context, IConfiguration configuration)
    {
        Configure<AbpBackgroundJobOptions>(options => options.IsJobExecutionEnabled = BackgroundJobConsts.IsEnabled);
        Configure<AbpBackgroundWorkerOptions>(options => options.IsEnabled = BackgroundJobConsts.IsEnabled);

        if (BackgroundJobConsts.IsEnabled)
        {
            context.Services.AddHangfire(config =>
            {
                config.UseSqlServerStorage(configuration.GetConnectionString("Default"));
            });
            context.Services.AddHangfireServer();
        }
    }

    private void ConfigureBlobStorage()
    {
        Configure<AbpBlobStoringOptions>(options =>
        {
            options.Containers.ConfigureDefault(container =>
            {
                container.UseDatabase();
            });
        });
    }

    private void ConfigureBundles()
    {
        Configure<AbpBundlingOptions>(options =>
        {
            options.StyleBundles.Configure(
                LeptonXThemeBundles.Styles.Global,
                bundle =>
                {
                    bundle.AddFiles("/global-styles.css");
                }
            );
        });
    }

    private void ConfigureCache()
    {
        Configure<AbpDistributedCacheOptions>(options =>
        {
            options.KeyPrefix = "CabMD:";
        });
    }

    private void ConfigureJsonSerialization()
    {
        Configure<AbpJsonOptions>(options =>
        {
            //options.UseHybridSerializer = false;
        });
        Configure<AbpSystemTextJsonSerializerOptions>(options =>
        {
            ////options.JsonSerializerOptions.Converters.Add(new JsonNonStringKeyDictionaryConverterFactory());
            //options.JsonSerializerOptions.Converters.Add(new DiagnosticCodes.Diagnostic_Code.Diagnostic_CodeSystemTextJsonConverter());
            //options.JsonSerializerOptions.Converters.Add(new MasterNumbers.Master_Number.Master_NumberSystemTextJsonConverter());
            //options.JsonSerializerOptions.Converters.Add(new CabMD.Patients.Province_Code.Province_CodeSystemTextJsonConverter());
            CabMDJsonSerializationOptions.SetConverters(options.JsonSerializerOptions);
        });
        //Configure<AbpNewtonsoftJsonSerializerOptions>(options =>
        //{
        //    options.Converters.Add<AbpJsonIsoDateTimeConverter>();
        //});
    }

    private void ConfigureLayoutChanges(IConfiguration configuration)
    {
        Configure<AbpBundlingOptions>(options =>
        {
            options.StyleBundles.Configure(LeptonXThemeBundles.Styles.Global,
                bundle =>
                {
                    bundle.AddContributors(typeof(KendoStyleContributor));
                });
            options
                .StyleBundles
                .Get(StandardBundles.Styles.Global)
                .Contributors.Remove<FontAwesomeStyleContributor>(); // Do this so we can use pro kit
        });

        Configure<AbpLayoutHookOptions>(options =>
        {
            options.Add(
                LayoutHooks.Head.Last, //The hook name
                typeof(KendoViewComponent) //The component to add
            );

            options.Add(LayoutHooks.Body.Last, typeof(KendoDeferredViewComponent));

            options.Add(
                LayoutHooks.Head.Last, //The hook name
                typeof(FontAwesomeViewComponent) // Add the pro kit
            );

            if (configuration.GetValue<bool>("Intercom:Enabled", false))
            {
                options.Add(
                    LayoutHooks.Head.First,
                    typeof(IntercomViewComponent));
            }

            if (configuration.GetValue<bool>("App:EnableMiniProfiler", false))
            {
                options.Add(
                    LayoutHooks.Body.Last,
                    typeof(MiniProfilerViewComponent));
            }
        });
    }

    private void ConfigureMultiTenancy()
    {
        Configure<AbpMultiTenancyOptions>(options => { options.IsEnabled = MultiTenancyConsts.IsEnabled; });
    }

    private void ConfigureNavigationServices(IConfiguration configuration)
    {
        Configure<AbpNavigationOptions>(options =>
        {
            options.MenuContributors.Add(new CabMDMenuContributor(configuration));
        });

        Configure<AbpToolbarOptions>(options =>
        {
            options.Contributors.Add(new CabMDToolbarContributor());
        });
    }

    private void ConfigurePages()
    {
        Configure<RazorPagesOptions>(options =>
        {
            options.Conventions.AuthorizePage("/HostDashboard", CabMDPermissions.Dashboard.Host);
            options.Conventions.AuthorizePage("/TenantDashboard", CabMDPermissions.Dashboard.Tenant);
            options.Conventions.AuthorizePage("/Plans/Index", CabMDPermissions.Plans.Default);
            options.Conventions.AuthorizePage("/CareProviders/Index", CabMDPermissions.CareProviders.Default);
            options.Conventions.AuthorizePage("/MasterNumbers/Index", CabMDPermissions.MasterNumbers.Default);
            options.Conventions.AuthorizePage("/DiagnosticCodes/Index", CabMDPermissions.DiagnosticCodes.Default);
            options.Conventions.AuthorizePage("/Services/Index", CabMDPermissions.Services.Default);
        });

        Configure<RouteOptions>(options =>
        {
            options.ConstraintMap.Add("claimstate", typeof(ClaimStateConstraint));
            options.ConstraintMap.Add("patientid", typeof(PatientIdConstraint));
        });
    }
}

Here's the auth module def:

DependsOn(
        typeof(AbpAutofacModule),
        typeof(AbpCachingStackExchangeRedisModule),
        typeof(AbpAspNetCoreSerilogModule),
        typeof(AbpAccountPublicWebOpenIddictModule),
        typeof(AbpAspNetCoreMvcUiLeptonXThemeModule),
        typeof(AbpAccountPublicApplicationModule),
        typeof(AbpDistributedLockingModule),
        typeof(CabMDEntityFrameworkCoreModule)
        )]
    public class CabMDAuthServerModule : AbpModule
    {
        private static X509Certificate2 GetSigningCertificate(IConfiguration configuration)
        {
            // try thumbprint first, most secure
            // Note: You need to make sure WEBSITE_LOAD_CERTIFICATES={thumbprint} is on the Azure settings or
            // the cert won't be found. See: https://learn.microsoft.com/en-us/azure/app-service/configure-ssl-certificate-in-code
            var certThumbprint = configuration.GetValue<string>("SigningCertificate:Thumbprint") ?? string.Empty;
            if (!string.IsNullOrEmpty(configuration.GetValue<string>("SigningCertificate:Thumbprint")))
            {
                using var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                var validOnly = false;
                certStore.Open(OpenFlags.ReadOnly);

                var certCollection = certStore.Certificates.Find(
                                            X509FindType.FindByThumbprint,
                                            certThumbprint,
                                            validOnly);

                // Get the first cert with the thumbprint
                var cert = certCollection.OfType<X509Certificate2>().FirstOrDefault();

                if (cert is null)
                    throw new Exception($"Certificate with thumbprint {certThumbprint} was not found");

                // Use certificate
                return cert;
            }
            else
            {
                // try a physical file as fallback, less secure as we need to provide password and the file is static
                var certPath = configuration.GetValue<string>("SigningCertificate:Path");
                if (!string.IsNullOrEmpty(certPath) && File.Exists(certPath))
                {
                    return new X509Certificate2(certPath, configuration.GetValue<string>("SigningCertificate:Password"));
                }
                else
                {
                    throw new Exception($"Certificate with SigningCertificate:Path '{certPath}' was not found");
                }
            }
        }

        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            var hostingEnvironment = context.Services.GetHostingEnvironment();
            var configuration = context.Services.GetConfiguration();

            PreConfigure<OpenIddictBuilder>(builder =>
            {
                builder.AddValidation(options =>
                {
                    options.AddAudiences("CabMD");
                    options.UseLocalServer();
                    options.UseAspNetCore();
                });
            });

            if (!hostingEnvironment.IsDevelopment())
            {
                PreConfigure<AbpOpenIddictAspNetCoreOptions>(options =>
                {
                    options.AddDevelopmentEncryptionAndSigningCertificate = false;
                });

                PreConfigure<OpenIddictServerBuilder>(builder =>
                {
                    builder.AddSigningCertificate(GetSigningCertificate(configuration));
                    builder.AddEncryptionCertificate(GetSigningCertificate(configuration));
                    builder.SetIssuer(new Uri(configuration["AuthServer:Authority"]));
                });
            }
        }

        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var hostingEnvironment = context.Services.GetHostingEnvironment();
            var configuration = context.Services.GetConfiguration();

            if (!Convert.ToBoolean(configuration["App:DisablePII"]))
            {
                Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;
            }

            if (!Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]))
            {
                Configure<OpenIddictServerAspNetCoreOptions>(options =>
                {
                    options.DisableTransportSecurityRequirement = true;
                });
            }

            context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme);

            Configure<AbpLocalizationOptions>(options =>
            {
                options.Resources
                    .Get<CabMDResource>()
                    .AddBaseTypes(
                        typeof(AbpUiResource)
                    );
            });

            Configure<AbpBundlingOptions>(options =>
            {
                options.StyleBundles.Configure(
                    LeptonXThemeBundles.Styles.Global,
                    bundle =>
                    {
                        bundle.AddFiles("/global-styles.css");
                    }
                );
            });

            Configure<AbpAuditingOptions>(options =>
            {
                //options.IsEnabledForGetRequests = true;
                options.ApplicationName = "AuthServer";
            });

            if (hostingEnvironment.IsDevelopment())
            {
                Configure<AbpVirtualFileSystemOptions>(options =>
                {
                    options.FileSets.ReplaceEmbeddedByPhysical<CabMDDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}CabMD.Domain.Shared", Path.DirectorySeparatorChar)));
                    options.FileSets.ReplaceEmbeddedByPhysical<CabMDDomainModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}CabMD.Domain", Path.DirectorySeparatorChar)));
                });
            }

            Configure<AppUrlOptions>(options =>
            {
                options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"];
                options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"].Split(','));
            });

            Configure<AbpBackgroundJobOptions>(options =>
            {
                options.IsJobExecutionEnabled = false;
            });

            Configure<AbpDistributedCacheOptions>(options =>
            {
                options.KeyPrefix = "CabMD:";
            });

            var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("CabMD");
            if (!hostingEnvironment.IsDevelopment())
            {
                var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
                dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "CabMD-Protection-Keys");
            }

            context.Services.AddSingleton<IDistributedLockProvider>(sp =>
            {
                var connection = ConnectionMultiplexer
                    .Connect(configuration["Redis:Configuration"]);
                return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
            });

            context.Services.AddCors(options =>
            {
                options.AddDefaultPolicy(builder =>
                {
                    builder
                        .WithOrigins(
                            configuration["App:CorsOrigins"]
                                .Split(",", StringSplitOptions.RemoveEmptyEntries)
                                .Select(o => o.RemovePostFix("/"))
                                .ToArray()
                        )
                        .WithAbpExposedHeaders()
                        .SetIsOriginAllowedToAllowWildcardSubdomains()
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials();
                });
            });

            context.Services.AddAuthentication()
                .AddGoogle(GoogleDefaults.AuthenticationScheme, _ => { })
                .WithDynamicOptions<GoogleOptions, GoogleHandler>(
                    GoogleDefaults.AuthenticationScheme,
                    options =>
                    {
                        options.WithProperty(x => x.ClientId);
                        options.WithProperty(x => x.ClientSecret, isSecret: true);
                    }
                )
                .AddMicrosoftAccount(MicrosoftAccountDefaults.AuthenticationScheme, options =>
                {
                    //Personal Microsoft accounts as an example.
                    options.AuthorizationEndpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize";
                    options.TokenEndpoint = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token";
                })
                .WithDynamicOptions<MicrosoftAccountOptions, MicrosoftAccountHandler>(
                    MicrosoftAccountDefaults.AuthenticationScheme,
                    options =>
                    {
                        options.WithProperty(x => x.ClientId);
                        options.WithProperty(x => x.ClientSecret, isSecret: true);
                    }
                )
                .AddTwitter(TwitterDefaults.AuthenticationScheme, options => options.RetrieveUserDetails = true)
                .WithDynamicOptions<TwitterOptions, TwitterHandler>(
                    TwitterDefaults.AuthenticationScheme,
                    options =>
                    {
                        options.WithProperty(x => x.ConsumerKey);
                        options.WithProperty(x => x.ConsumerSecret, isSecret: true);
                    }
                );

            context.Services.Configure<AbpAccountOptions>(options =>
            {
                options.TenantAdminUserName = "admin";
                options.ImpersonationTenantPermission = SaasHostPermissions.Tenants.Impersonation;
                options.ImpersonationUserPermission = IdentityPermissions.Users.Impersonation;
            });

            Configure<LeptonXThemeOptions>(options =>
            {
                options.DefaultStyle = LeptonXStyleNames.System;
            });
        }

        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseAbpRequestLocalization();

            if (!env.IsDevelopment())
            {
                app.UseErrorPage();
                app.UseHsts();
                app.UseHttpsRedirection();
            }

            app.UseCorrelationId();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseCors();
            app.UseAuthentication();
            app.UseAbpOpenIddictValidation();

            if (MultiTenancyConsts.IsEnabled)
            {
                app.UseMultiTenancy();
            }

            app.UseUnitOfWork();
            app.UseAuthorization();

            app.UseAuditing();
            app.UseAbpSerilogEnrichers();
            app.UseConfiguredEndpoints();

            if (!env.IsDevelopment())
            {
                app.Use((httpContext, next) =>
                {
                    httpContext.Request.Scheme = "https";
                    return next();
                });
            }
        }
    }

Yea, I followed the example I think along with the migration docs.

That project isn't using LeptonX, which we are.

Here are the Log files you asked for.

[DependsOn(
    typeof(CabMDHttpApiModule),
    typeof(CabMDHttpApiClientModule),
    typeof(AbpAspNetCoreAuthenticationOpenIdConnectModule),
    typeof(AbpAspNetCoreMvcClientModule),
    typeof(AbpAutofacModule),
    typeof(AbpCachingStackExchangeRedisModule),
    typeof(AbpFeatureManagementWebModule),
    typeof(AbpAccountAdminWebModule),
    typeof(AbpHttpClientIdentityModelWebModule),
    typeof(AbpIdentityWebModule),
    typeof(AbpAuditLoggingWebModule),
    typeof(AbpAspNetCoreMvcUiLeptonXThemeModule),
    typeof(SaasHostWebModule),
    typeof(AbpOpenIddictProWebModule),
    typeof(LanguageManagementWebModule),
    typeof(TextTemplateManagementWebModule),
    typeof(AbpSwashbuckleModule),
    typeof(AbpAspNetCoreSerilogModule),
    typeof(AbpPaymentPayuWebModule),
    typeof(AbpPaymentTwoCheckoutWebModule),
    typeof(AbpPaymentWebModule),
    typeof(FileManagementWebModule),
    typeof(DocsWebModule),
    typeof(CabMDReportingModule),
    typeof(CmsKitProWebModule),
    typeof(AbpBlobStoringModule),
    typeof(AbpTextTemplatingScribanModule)
)]

I think the issue is with this line:

filename = Path.Combine(Directory.GetCurrentDirectory(), "tempkey.rsa");

https://github.com/abpframework/abp/blob/e3e1779de6df5d26f01cdc8e99ac9cbcb3d24d3c/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerBuilderExtensions.cs#L76

Need to use an option there, or find some way to specify filename so that the GetCurrentDirectory isn't used in this context.

Showing 11 to 20 of 36 entries
Made with ❤️ on ABP v9.0.0-preview Updated on September 19, 2024, 10:13