I have the following error in my solution running on ABP 4.3.0 after submitting a new password in the forgotten password box: "VerifyUserTokenAsync() failed with purpose: ResetPassword for user."
I test everything on localhost in VS debug mode using a non-default tenant. As far as I remember, it used to work in the ABP 3.x.x. Any ideas, suggestions?
On other hand, ResetPassword
works OK in test generated 4.3.0 solution on default tenant. So I cannot figure out what could be wrong...
What I have noticed is that ResetToken
is a bit shorter in Test app...
Just in case if it matters: I have custom ProfileAppService
.
Please make a note I am trying this code now:
public override async Task ResetPasswordAsync(ResetPasswordDto input)
{
await IdentityOptions.SetAsync();
var user = await UserManager.GetByIdAsync(input.UserId);
(await UserManager.ResetPasswordAsync(user, input.ResetToken, input.Password)).CheckErrors();
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.ChangePassword
});
}
But since I need to change the password for ALL TENANTS having such loginname I will need to use a custom implementation of AccountAppService
:
public override async Task ResetPasswordAsync(ResetPasswordDto input)
{
await IdentityOptions.SetAsync();
var currentUser = await UserManager.GetByIdAsync(input.UserId);
var tenants = await _abxUserRepository.FindTenantsByLoginAsync(currentUser.UserName);
foreach (var tenant in tenants)
{
using (CurrentTenant.Change(tenant.AbpId))
{
var tenantUser = await UserManager.GetByIdAsync(input.UserId);
// Generate reset token for tenantUser!
(await UserManager.ResetPasswordAsync(tenantUser, /*resetToken for tenantUser */, input.Password)).CheckErrors();
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.ChangePassword
});
}
}
}
I've upgraded our solution from ABP 3.3.2 to 4.3.0.
Everything was more or less smoothly, but now I discovered a problem: some new ABP tables are missing from migration scripts! How come? What am I supposed to do now?
Please have a look at the migration classes autogenerated for 3.3.2 and 4.3.0. https://1drv.ms/u/s!AhWdpZddvifTtizt4xjre044i7B8?e=0xuBUs
Here is the list of ABP-prefixed tables created from test solution (autogenerated in ABP Suite) using DbMigrator
project in local MS SQL server DB - all the tables are at place:
Here is the list of tables in our ORACLE DB created using standard update-database
command and DbMigrator
afterwards to seed data - make a note some tables are missing (for instance, AbpBlobContainers, AbpTextTemplateContents). How it's possible?? How to easily find out what is missing and add it?
The missing table has been identified while trying to use "Forgot password" functionality: it appeared this functionality now needs to access AbpTextTemplateContents table.
So please advice how to make Forgot password work having AbpTextTemplateContents at place. Also make a note: I need to intercept change password functionality (override Identity Account Service?) - I need to change password for all users with the same loginname at other tenants!
And if I get it right - ABP documentation needs to be updated here. Now:
How to Install Text Template Management module is pre-installed in the startup templates. So, no need to manually install it.
To be changed to:
How to Install If you are using ABP version 4.x.x (where this module appeared?) Text Template Management module is pre-installed in the startup templates. So, no need to manually install it. If you are using ABP version 3.x.x - you have to ....
3.3.2 / Angular
We are extending HangfireDashboard
- adding custom tab for handling recurring jobs. As a base, we are about to use existing Github extension (RecurringJobAdmin
) which is plumbed like this:
private void ConfigureHangfire(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddHangfire(globalConfig =>
{
globalConfig
.UseStorage(new OracleStorage(configuration.GetConnectionString("Default")))
.UseRecurringJobAdmin(typeof(CentralToolsApplicationModule).Assembly);
});
}
However here is where the problem is: this extension uses own UI styles and Vue as JS Framework. We don't want to keep using it as a Nuget package. Instead, we would like to have own Module - with the same UI as other pages and get rid of Vue (in favor of Angular or without it). Here's what it looks like:
The questions are:
RecurringJobAdmin
extension uses just a sole Vue.js file to handle this; So is there an easier solution? What we would need though is 'change detection' on Admin page and of course data exchange between client and server part;3.3.1 / Angular
Hi ABP team.
I created solution as an ABP module. At this moment i would like to check for permissions which were granted for a user's roles. I'm using IsGrantedAsync
method of IPermissionStore
interface. But this method returns negative result every time. I'm using "* .HttpApi.Host" project to run and test my solution.
Also I've found out that information about user isn't complete: the user's roles are absent in CurrentUser
member of ApplicationService
object, but access token contains this data.
Could you please suggest what I did wrong and how it can be fixed?
I would like to add a custom provider name like "Q", what am I supposed to do in this case and how to make IPermissionStore
interface methods work with a new provider name?
After upgrading to the ABP version where login workflow changed, our published Azure app stopped logging user in - it just redirects back to login page. We don't know what settings need to be changed.
Here are the details:
some hand-made SSL certificate is installed
configurations are as follows:
`
const baseUrl = 'https://xxxxxx.azure.com/CentralTools';
export const environment = {
production: false,
application: {
baseUrl,
name: 'CentralTools'
},
oAuthConfig: {
issuer: 'https://xxxxxx.azure.com/identityserver',
redirectUri: baseUrl,
clientId: 'CentralTools_App',
dummyClientSecret: '1q2w3e*',
scope: 'CentralTools AuditLogging offline_access',
strictDiscoveryDocumentValidation: true,
timeoutFactor: 0.9, // default value is 0.75 - Timeout for updating access_token
responseType: 'code', // This is parameter is required in order to get new access_token via refresh token
showDebugInformation: true,
requireHttps: true
},
apis: {
default: {
url: 'https://xxxxxx.azure.com/httpapihost'
},
AuditLogging: {
url: 'https://xxxxxx.azure.com/auditlogging'
}
},
localization: {
defaultResourceName: 'CentralTools'
}
};
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
app.UseCookiePolicy(new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Lax
});
var env = context.GetEnvironment();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAbpRequestLocalization();
app.UseHsts();
app.UseHttpsRedirection();
if (!env.IsDevelopment())
{
app.UseErrorPage();
}
app.UseCors(DefaultCorsPolicyName);
app.UseCorrelationId();
app.UseVirtualFiles();
app.UseRouting();
app.UseAuthentication();
if (MultiTenancyConsts.IsEnabled)
{
app.UseMultiTenancy();
}
app.UseIdentityServer();
app.UseAuthorization();
app.UseAuditing();
app.UseConfiguredEndpoints();
}
{
"App": {
"SelfUrl": "https://xxxxxx.azure.com/IdentityServer",
"CorsOrigins": "https://xxxxxx.azure.com,https://localhost/CentralTools"
},
...
}
We want to work with some service inside AutoMapper profile. Below is just the idea which does not work. Please suggest how to implement such DI:
private void ConfigureAutoMapper(ServiceConfigurationContext context)
{
context.Services.AddSingleton(provider => new AutoMapper.MapperConfiguration(cfg =>
{
//TODO: implement
cfg.AddProfile(new CentralToolsApplicationAutoMapperProfile
(
provider.GetService<IBlobContainer<FileContainer>>()
));
}).CreateMapper());
}
public class CentralToolsApplicationAutoMapperProfile : AutoMapper.Profile
{
//TODO: implement
public CentralToolsApplicationAutoMapperProfile()
{
CreateMap(...);
CreateMap(...);
}
}
public class MyCustomUserMapper : IObjectMapper<User, UserDto>, ITransientDependency
approach seems not to be useful for our case.
Hi, we can see that meanwhile token lifetime is not prolonged per each request in UI, there is a fixed lifetime that is configured (1 year by default for now, as far as I remember). We want to provide a specific token life, like 15 mins and to prolong token lifetime per each request by this value. How would you recommend to do that?
Hi, we are using Tenants functionality and noticed it's only possible to create a tenant in UI by a user logged in under a 'null'-tenant (super tenant?) We need to create tenants by a user, logged in under ANOTHER tenant - we have a custom tree-like structure of tenants in our system.
Hi, our business model requires one user to belong to several tenants. So we have created accounts for the same user, where each account has the same user name, but different tenant id.