Hi,
Seems the problem is not related to ABP but Electron.
See: https://github.com/electron/electron/issues/345 https://github.com/electron/electron/issues/15404#issuecomment-433546435
You may need to disable the nodeIntegration
Hi,
As I understand, a customer is a tenant. a facility can belong to multiple customers.
Just an idea:
The Facility entity should not implement the IMultiTenant interface, so It will be in the host database.
public class Facility: ...
{
public List<Guid> TenantIds {get; set;}
}
public class TestAppService:....
{
private readonly IRepository<Facility, Guid> _reopsitory;
.....
public async Task GetReportAsync()
{
var currentTenantId = CurrentTenant.GetId();
//Switch to host
using(CurrentTenant.Change(null))
{
var result = await _reopsitory.GetListAsync(x => x.TenantIds.Contains(currentTenantId));
}
}
}
is it a way to refresh redis?
I didn't get it.
I tested on my localhost and it works. Also something interesting is, any idea why jquery is not on production ?
The bundle system will bundles & minifies for the production environment: https://docs.abp.io/en/abp/latest/UI/AspNetCore/Bundling-Minification#bundling-mode
You can try configuring the AbpBundlingOptions or ignore Jquery file.
Configure<AbpBundlingOptions>(options =>
{
options.Mode = BundlingMode.None;
});
Or..
Configure<AbpBundlingOptions>(options =>
{
options.MinificationIgnoredFiles.Add("/lib/jquery/jquery.js");
});
Hi,
This is a bug, we will fix it in the next patch version, and your ticket refunded.
is it possible to override a bundles, global bundles to make jquery be present first. is it possible to override the main layout.cshtml like vies/pages/_Layout.cshtml to load jquery manually here
Hi,
You can try:
public class MyBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Insert(0, "/lib/jquery/jquery.js");
}
}
Configure<AbpBundlingOptions>(options =>
{
options.ScriptBundles.Configure(
LeptonXThemeBundles.Scripts.Global,
bundle =>
{
bundle.AddContributors(new MyBundleContributor());
}
);
});
https://github.com/abpframework/abp/pull/18264
The count seems to include users that have been soft deleted which we believe is misleading to users.
Yes, that is the problem, we have enhanced this in 8.0: https://github.com/abpframework/abp/pull/18051
I will do the same in 7.4.
You may need to manually delete the records in the table AbpUserRoles.
HI,
Ok, you can try override the OnGetExternalLoginCallbackAsync method
[ExposeServices(typeof(LoginModel))]
public class MyLoginModel : LoginModel
{
[UnitOfWork]
public override async Task<IActionResult> OnGetExternalLoginCallbackAsync(string returnUrl = "", string returnUrlHash = "", string remoteError = null)
{
if (remoteError != null)
{
Logger.LogWarning($"External login callback error: {remoteError}");
return RedirectToPage("./Login");
}
await IdentityOptions.SetAsync();
var loginInfo = await SignInManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
Logger.LogWarning("External login info is not available");
return RedirectToPage("./Login");
}
IsLinkLogin = await VerifyLinkTokenAsync();
var result = await SignInManager.ExternalLoginSignInAsync(
loginInfo.LoginProvider,
loginInfo.ProviderKey,
isPersistent: true,
bypassTwoFactor: true
);
if (!result.Succeeded)
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = "Login" + result
});
}
if (result.IsLockedOut)
{
Logger.LogWarning($"Cannot proceed because user is locked out!");
return RedirectToPage("./LockedOut", new {
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash
});
}
if (result.IsNotAllowed)
{
Logger.LogWarning($"External login callback error: User is Not Allowed!");
var user = await UserManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey);
if (user.IsActive)
{
await StoreConfirmUser(user);
return RedirectToPage("./ConfirmUser", new {
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash
});
}
return RedirectToPage("./Login");
}
if (result.Succeeded)
{
var user = await UserManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey);
if (IsLinkLogin)
{
using (CurrentPrincipalAccessor.Change(await SignInManager.CreateUserPrincipalAsync(user)))
{
await IdentityLinkUserAppService.LinkAsync(new LinkUserInput
{
UserId = LinkUserId.Value,
TenantId = LinkTenantId,
Token = LinkToken
});
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentityProSecurityLogActionConsts.LinkUser,
UserName = user.UserName,
ExtraProperties =
{
{ IdentityProSecurityLogActionConsts.LinkTargetTenantId, LinkTenantId },
{ IdentityProSecurityLogActionConsts.LinkTargetUserId, LinkUserId }
}
});
using (CurrentTenant.Change(LinkTenantId))
{
var targetUser = await UserManager.GetByIdAsync(LinkUserId.Value);
using (CurrentPrincipalAccessor.Change(await SignInManager.CreateUserPrincipalAsync(targetUser)))
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentityProSecurityLogActionConsts.LinkUser,
UserName = targetUser.UserName,
ExtraProperties =
{
{ IdentityProSecurityLogActionConsts.LinkTargetTenantId, targetUser.TenantId },
{ IdentityProSecurityLogActionConsts.LinkTargetUserId, targetUser.Id }
}
});
}
}
}
}
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = result.ToIdentitySecurityLogAction(),
UserName = user.UserName
});
return RedirectSafely(returnUrl, returnUrlHash);
}
var email = loginInfo.Principal.FindFirstValue(AbpClaimTypes.Email);
if (email.IsNullOrWhiteSpace())
{
return RedirectToPage("./Register", new {
IsExternalLogin = true,
ExternalLoginAuthSchema = loginInfo.LoginProvider,
ReturnUrl = returnUrl
});
}
//-------- this is the source code, you can change it.------------
var externalUser = await UserManager.FindByEmailAsync(email);
if (externalUser == null)
{
externalUser = await CreateExternalUserAsync(loginInfo);
}
else
{
if (await UserManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey) == null)
{
CheckIdentityErrors(await UserManager.AddLoginAsync(externalUser, loginInfo));
}
}
if (await HasRequiredIdentitySettings())
{
Logger.LogWarning($"New external user is created but confirmation is required!");
await StoreConfirmUser(externalUser);
return RedirectToPage("./ConfirmUser", new {
returnUrl = ReturnUrl,
returnUrlHash = ReturnUrlHash
});
}
await SignInManager.SignInAsync(externalUser, false);
if (IsLinkLogin)
{
using (CurrentPrincipalAccessor.Change(await SignInManager.CreateUserPrincipalAsync(externalUser)))
{
await IdentityLinkUserAppService.LinkAsync(new LinkUserInput
{
UserId = LinkUserId.Value,
TenantId = LinkTenantId,
Token = LinkToken
});
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentityProSecurityLogActionConsts.LinkUser,
UserName = externalUser.UserName,
ExtraProperties =
{
{ IdentityProSecurityLogActionConsts.LinkTargetTenantId, LinkTenantId },
{ IdentityProSecurityLogActionConsts.LinkTargetUserId, LinkUserId }
}
});
using (CurrentTenant.Change(LinkTenantId))
{
var targetUser = await UserManager.GetByIdAsync(LinkUserId.Value);
using (CurrentPrincipalAccessor.Change(await SignInManager.CreateUserPrincipalAsync(targetUser)))
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentityProSecurityLogActionConsts.LinkUser,
UserName = targetUser.UserName,
ExtraProperties =
{
{ IdentityProSecurityLogActionConsts.LinkTargetTenantId, targetUser.TenantId },
{ IdentityProSecurityLogActionConsts.LinkTargetUserId, targetUser.Id }
}
});
}
}
}
}
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = result.ToIdentitySecurityLogAction(),
UserName = externalUser.Name
});
return RedirectSafely(returnUrl, returnUrlHash);
}
}
it will still attempt to find the user every time and not be able to find it
Sorry, I didn't get it.