For this, you can override the Login page and remove the relevant code blocks. You can follow the steps below to override the login page.
1-) Create Account folder in Pages folder like below:
2-) Create Login.cshtml file in Account folder in your AuthServer.
3-) Update Login.cshtml file like below:
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options
@using Owl.reCAPTCHA
@using Volo.Abp.Account.Localization
@using Volo.Abp.Account.Public.Web.Pages.Account;
@using Volo.Abp.Account.Public.Web.Security.Recaptcha
@using Volo.Abp.Account.Settings
@using Volo.Abp.Identity;
@using Volo.Abp.Settings
@model Volo.Abp.Account.Public.Web.Pages.Account.LoginModel
@inject IHtmlLocalizer<AccountResource> L
@inject Volo.Abp.AspNetCore.Mvc.UI.Layout.IPageLayout PageLayout
@inject ISettingProvider SettingProvider
@{
PageLayout.Content.Title = L["Login"].Value;
var reCaptchaVersion = await SettingProvider.GetAsync<int>(AccountSettingNames.Captcha.Version);
if (Model.UseCaptcha)
{
await Model.ReCaptchaOptions.SetAsync(reCaptchaVersion == 3 ? reCAPTCHAConsts.V3 : reCAPTCHAConsts.V2);
}
}
@section scripts
{
<abp-script-bundle name="@typeof(LoginModel).FullName">
<abp-script src="/Pages/Account/Login.js" />
</abp-script-bundle>
@if (Model.UseCaptcha)
{
if (reCaptchaVersion == 3)
{
<recaptcha-script-v3 />
<recaptcha-script-v3-js action="login" execute="false" />
}
else
{
<recaptcha-script-v2 />
}
}
}
@if (Model.IsLinkLogin)
{
<abp-alert alert-type="Warning">
@L["LinkAccountWarning", Url.PageLink()]
</abp-alert>
}
@if (Model.BackToExternalLogins)
{
<div class="d-grid gap-2">
<a class="mb-3 btn btn-primary btn-block" href="@Url.Page("./ExternalLogins")">@L["Back"]</a>
</div>
}
@if (Model.ShowRequireMigrateSeedMessage)
{
<div class="alert alert-danger">
<h4 class="alert-heading">@L["RequireMigrateSeedTitle"]</h4>
<p>@L["RequireMigrateSeedMessage"]</p>
</div>
}
<div class="account-module-form">
@if (Model.IsSelfRegistrationEnabled)
{
<h5 class="mb-2">@L["NotAMemberYet"] <a class="text-decoration-none" href="@Url.Page("./Register", new {returnUrl = Model.ReturnUrl, returnUrlHash = Model.ReturnUrlHash})">@L["Register"]</a></h5>
}
@if (Model.EnableLocalLogin)
{
<form method="post" id="loginForm">
@if (Model.UseCaptcha)
{
<input class="mb-3" data-captcha="true" type="hidden" name="@RecaptchaValidatorBase.RecaptchaResponseKey" id="@RecaptchaValidatorBase.RecaptchaResponseKey"/>
}
<div>
<div class="form-floating mb-2">
<input asp-for="LoginInput.UserNameOrEmailAddress" type="text" class="form-control" placeholder="name@example.com">
@Html.LabelFor(m => m.LoginInput.UserNameOrEmailAddress)
<span asp-validation-for="LoginInput.UserNameOrEmailAddress"/>
</div>
<div class="form-floating mb-2">
<input asp-for="LoginInput.Password" id="password-input" type="password" class="form-control" placeholder="Password">
@Html.LabelFor(m => m.LoginInput.Password)
<i id="PasswordVisibilityButton" class="bi bi-eye-slash show-pass-icon" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-html="true" aria-label="@L["ShowPassword"]" data-bs-original-title="@L["ShowPassword"]"></i>
<i id="capslockicon" class="bi bi-capslock caps-lock-icon" style="display: none;" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-html="true" aria-label="<i class='bi bi-exclamation-circle'></i> @L["CapsLockOn"]!" data-bs-original-title="<i class='bi bi-exclamation-circle'></i> @L["CapsLockOn"]!"></i>
<span asp-validation-for="LoginInput.Password"/>
</div>
</div>
<abp-row>
<abp-column>
<div class="form-switch ps-2">
<abp-input asp-for="LoginInput.RememberMe" class="mb-4"/>
</div>
</abp-column>
<abp-column class="text-end">
<a href="@Url.Page("./ForgotPassword", new {returnUrl = Model.ReturnUrl, returnUrlHash = Model.ReturnUrlHash})">@L["ForgotPassword"]</a>
</abp-column>
</abp-row>
@if (reCaptchaVersion == 2)
{
<script>
recaptchaCallback = function (token) {
$('form button[type=submit]').removeAttr("disabled");
$('#@RecaptchaValidatorBase.RecaptchaResponseKey').val(token)
};
</script>
<div class="mb-3">
<recaptcha-div-v2 callback="recaptchaCallback"/>
</div>
}
<div class="d-grid gap-2">
<abp-button button-type="Primary" type="submit" class="mb-3" name="Action" value="Login" disabled="true">
<i class="bi bi-box-arrow-in-right me-1"></i>
@L["Login"]
</abp-button>
</div>
@if (Model.ShowCancelButton)
{
<div class="d-grid gap-2">
<abp-button button-type="Secondary" type="submit" formnovalidate="formnovalidate" class="mb-3" name="Action" value="Cancel">@L["Cancel"]</abp-button>
</div>
}
</form>
}
@if (Model.VisibleExternalProviders.Any())
{
if(Model.EnableLocalLogin)
{
<hr/>
@L["OrSignInWith"]
<br/>
}
else
{
@L["SignInWithOneOfTheFollowingProviders"]
}
<form asp-page="./Login" asp-page-handler="ExternalLogin"
asp-route-returnUrl="@Model.ReturnUrl"
asp-route-returnUrlHash="@Model.ReturnUrlHash"
asp-route-linkTenantId="@Model.LinkTenantId"
asp-route-linkUserId="@Model.LinkUserId"
asp-route-linkToken="@Model.LinkToken"
method="post">
@foreach (var provider in Model.VisibleExternalProviders)
{
<button type="submit"
class="mt-2 me-2 btn btn-outline-primary btn-sm"
name="provider"
value="@provider.AuthenticationScheme"
data-busy-text="@L["ProcessingWithThreeDot"]">
@if (provider.Icon != null)
{
<i class="@provider.Icon"></i>
}
<span>@provider.DisplayName</span>
</button>
}
</form>
}
</div>
You can then customize it any way you want. If you have a specific question in the implementation, you can ask.
Hi,
It’s possible that a rule in your CSS is overriding the branding logo. Could you please check your CSS files for any definitions that might affect the logo?
For example, in a Blazor WebAssembly project that uses the LeptonX theme, the logo is defined via CSS variables like this:
:root .lpx-theme-dim,
:root .lpx-theme-dark {
--lpx-logo: url('/images/logo/leptonx/icon.svg');
--lpx-logo-icon: url('/images/logo/leptonx/icon.svg');
}
:root .lpx-theme-light {
--lpx-logo: url('/images/logo/leptonx/icon.svg');
--lpx-logo-icon: url('/images/logo/leptonx/icon.svg');
}
You can try updating these CSS variables to point to your own logo file to see if it solves the issue.
If this does not resolve the issue, please send your application with the ticket number in an email to support@abp.io so that I can fix it in your code and inform you about the issue later.
Hi,
It seems like the issue is caused by jQuery not being loaded before your Login.js file is executed.
Since we cannot see the bundle configuration for the CustomLoginModel, we cannot confirm exactly what is included. However, you can try updating the script bundle reference from:
<abp-script-bundle name="@typeof(CustomLoginModel).FullName">
to:
<abp-script-bundle name="@typeof(LoginModel).FullName">
This change will load the default login model’s script bundle, which includes jQuery by default. If this resolves the issue, it confirms that your custom login model bundle is missing jQuery.
If the issue still persists after this change, could you please share the contents of your host module class? Additionally, let us know if this issue occurs only on the login page or on other pages as well. This information will help us further investigate.
Hi,
If you have configured AbpDistributedEntityEventOptions as follows, this may be the problem:
Configure<AbpDistributedEntityEventOptions>(options =>
{
options.AutoEventSelectors.AddAll();
});
Because the line options.AutoEventSelectors.AddAll(); causes an issue. I tested the following code instead, and it works as expected:
Configure<AbpDistributedEntityEventOptions>(options =>
{
// options.AutoEventSelectors.AddAll(); // do not use this method until next version of ABP
// Use following codes for your entities
options.AutoEventSelectors.Add<MyEntity1>();
options.AutoEventSelectors.Add<MyEntity2>();
});
We will address the AddAll issue in this PR: 🔧 https://github.com/abpframework/abp/pull/22471
Are the abp doing any kind of validation, like only specific format are allowed to upload the image
There is no format validation in the API endpoint, but only certain types of files are allowed to be selected from the UI.
also do abp check the file is valid/secured to proceed to store in the blob.
There is no such validation, I am not sure if it is necessary. Because, for example, if a user uploads an invalid image, it only affects them. We know that this does not affect other users or cause any securrity vulnerability.
Here are the impelemtation of SetProfilePictureAsync:
[Authorize]
public virtual async Task SetProfilePictureAsync(ProfilePictureInput input)
{
await SettingManager.SetForUserAsync(CurrentUser.GetId(), AccountSettingNames.ProfilePictureSource, input.Type.ToString());
var userIdText = CurrentUser.GetId().ToString();
if (input.Type != ProfilePictureType.Image)
{
if (await AccountProfilePictureContainer.ExistsAsync(userIdText))
{
await AccountProfilePictureContainer.DeleteAsync(userIdText);
}
}
else
{
if (input.ImageContent == null)
{
throw new NoImageProvidedException();
}
var imageStream = input.ImageContent.GetStream();
if (ProfilePictureOptions.Value.EnableImageCompression)
{
try
{
var compressResult = await ImageCompressor.CompressAsync(imageStream);
if (compressResult.Result is not null && imageStream != compressResult.Result && compressResult.Result.CanRead)
{
await imageStream.DisposeAsync();
imageStream = compressResult.Result;
}
}
catch (Exception e)
{
Logger.LogWarning(e, "Profile picture compression failed! User ID:" + CurrentUser.GetId());
}
}
await AccountProfilePictureContainer.SaveAsync(userIdText, imageStream, true);
}
}
Hi,
Can you [Dependency(ReplaceServices = true)] attribute on top of your branding provider like below:
[Dependency(ReplaceServices = true)]
public class BlazorWebiAppBrandingProvider : DefaultBrandingProvider
{
private IStringLocalizer<BlazorWebiApp9087Resource> _localizer;
public BlazorWebiApp9087BrandingProvider(IStringLocalizer<BlazorWebiApp9087Resource> localizer)
{
_localizer = localizer;
}
public override string AppName => _localizer["AppName"];
}
You can also check this document if you are thinking of switching from Lepton to LeptonX.
Hi,
Can you share the logs of your application (log.txt) located under Logs folder?
Hi,
I created a Blazor Web App project from scratch to reproduce your problem.
This application uses ABP packages with version 9.1.0.
I added the code you mentioned as in the picture but I could not reproduce the problem:
Result:
Can you create a project from scratch and try to reproduce this situation to make sure that the problem belongs to your case? If you can reproduce the problem in a project created from scratch, let me know the version of the project you created, etc. and I will try.
Hi,
If it does not fix your problem, please share your solution if it's possible via email (to support@abp.io with ticket number), so we can more quickly fix your problem.