Ends in:
7 DAYS
18 HRS
29 MIN
45 SEC
Ends in:
7 D
18 H
29 M
45 S
Open Closed

Hide Username From Create/Edit User #2691


User avatar
0
jackmcelhinney created
  • ABP Framework version: v5.0.1
  • UI type: Angular
  • DB provider: EF Core
  • Identity Server Separated (Angular): no

Hello! We are trying to hide the username field from the Create and Edit User forms and use the email address for the username instead.

I have successfully removed the username field from the Angular UI and moved the email field to the top like this:

export function removeUserNameContributor(
  propList: FormPropList<IdentityUserDto>
) {
  propList.dropByValue(
    'userName',
    (prop, text) => prop.name === text
  )
  let emailPropIndex = propList.findIndex(p => p.value.name == 'email');
  propList.addHead(propList.get(emailPropIndex).value);
  propList.dropByIndex(emailPropIndex + 1);
}

export const identityEntityCreateFormPropContributors: IdentityCreateFormPropContributors = {
  [eIdentityComponents.Users]: [
    removeUserNameContributor
  ]
}

export const identityEntityEditFormPropContributors: IdentityEditFormPropContributors = {
  [eIdentityComponents.Users]: [
    removeUserNameContributor
  ]
}

{
    path: 'identity',
    loadChildren: () => {
      import('./identity/identity.module').then(m => m.IdentityOverrideModule)
      return import('@volo/abp.ng.identity').then((m) => m.IdentityModule.forLazy({
        createFormPropContributors: identityEntityCreateFormPropContributors,
        editFormPropContributors: identityEntityEditFormPropContributors,
      }))
    }
},

I've also overwritten the CreateAsync method to set the username to the email address:

[Authorize(IdentityPermissions.Users.Create)]
public override async Task<IdentityUserDto> CreateAsync(IdentityUserCreateDto input)
{
    var user = new Volo.Abp.Identity.IdentityUser(
        GuidGenerator.Create(),
        input.Email,
        input.Email,
        CurrentTenant.Id
    );
    
    input.MapExtraPropertiesTo(user);

    (await UserManager.CreateAsync(user, input.Password)).CheckErrors();
    
    ...
}

But I am unable to remove the Required attribute from UserName on IdentityUserCreateDto so I get the following error from the form:

In my ...DtoExtensions.cs I have tried:

ObjectExtensionManager.Instance
.AddOrUpdateProperty<string > (
    new[]
    {
        typeof(IdentityUserCreateDto),
    },
    "UserName",
    options => 
    {
        options.Attributes.Clear();
        options.Validators.Clear();
    }
);

and

ObjectExtensionManager.Instance
.AddOrUpdate<IdentityUserCreateDto>(objConfig =>
{
    objConfig.AddOrUpdateProperty<string>("UserName", propertyConfig =>
    {
        propertyConfig.Attributes.Clear();
        propertyConfig.Validators.Clear();
    });
});

and have tried substituting IdentityUserCreateDto with IdentityUserCreateOrUpdateDtoBase but none of these solutions have removed the Required attribute.

Any ideas would be appreciated. Thanks!


2 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    The UserName is required, you need to change the module source code, but it has a lot of work to do.

    I've also overwritten the CreateAsync method to set the username to the email address:

    You can use email as a user name in the front end. it should be working.

  • User Avatar
    0
    jackmcelhinney created

    We're just visually hiding the concept of a UserName by setting UserName = EmailAddress. That way users are created and sign in using only their email address, with no option for a different username.

    I ended up solving my issue by adding a hidden userName property with a default value.

    export function removeUserNameContributor(
      propList: FormPropList<IdentityUserDto>
    ) {
      let previousUserNameProp = propList.get(propList.findIndex(p => p.value.name == 'userName')).value
      propList.dropByValue(
        'userName',
        (prop, text) => prop.name === text
      )
      propList.addHead({
        ...previousUserNameProp,
        visible: c => false,
        defaultValue: 'DEFAULTVALUE'
      } as FormProp<IdentityUserDto>);
    
      let emailPropIndex = propList.findIndex(p => p.value.name == 'email');
      propList.addHead(propList.get(emailPropIndex).value);
      propList.dropByIndex(emailPropIndex + 1);
    }
    

    Then in CreateAsync I ignore the default value in the username and only use the email to create the user.

    var user = new Volo.Abp.Identity.IdentityUser(
        GuidGenerator.Create(),
        input.Email,
        input.Email,
        CurrentTenant.Id
    );
    

    Now the username for all users will be their email address.

Made with ❤️ on ABP v9.1.0-preview. Updated on November 20, 2024, 13:06