JMIX - Allow users to change their passwords

JMIX version 1.2.3

With JMIX is there any way to allow users to change their passwords themselves without an Admin resetting their password for them manually?

Is there a screen that we need to extend to allow this functionality?

The framework provides the ChangePasswordDialog class, you can call it from any part of your application as follows:

    @Autowired
    private Screens screens;

    @Autowired
    private CurrentAuthentication currentAuthentication;

    @Subscribe("changePasswordBtn")
    public void onChangePasswordBtnClick(Button.ClickEvent event) {
        screens.create(ChangePasswordDialog.class)
                .withUsername(currentAuthentication.getUser().getUsername())
                .withCurrentPasswordRequired(true)
                .show();
    }
2 Likes

Hi Konstantin,

I’m having issues using this from menuitem via class. I manage to fire the method but am getting

NullPointerException: Cannot invoke “io.jmix.ui.Screens.create(java.lang.Class)” because “this.screens” is null

My class

package com.myapp.utils;

import io.jmix.core.security.CurrentAuthentication;
import io.jmix.securityui.screen.changepassword.ChangePasswordDialog;
import io.jmix.ui.Screens;
import io.jmix.ui.menu.MenuItem;
import io.jmix.ui.menu.MenuItemRunnable;
import io.jmix.ui.screen.FrameOwner;
import org.springframework.beans.factory.annotation.Autowired;

public class ChangeUserPasswordMenu implements MenuItemRunnable
{
	@Autowired
	private Screens screens;

	@Autowired
	private CurrentAuthentication currentAuthentication;

	@Override
	public void run(FrameOwner origin, MenuItem menuItem) {
		screens.create(ChangePasswordDialog.class)
			.withUsername(currentAuthentication.getUser().getUsername())
			.withCurrentPasswordRequired(true)
			.show();
	}
}

Called from menu item as

<item class="com.myapp.utils.ChangeUserPasswordMenu" />

Am I missing something or is this intended to be used only from existing screens and not from menu directly? Jmix 1.4.0.

Thanks,

J.

1 Like

Hi Julius,

You get NPE because your class is not a Spring bean and @Autowired annotations don’t work for it, so the fields are null.

You should either make it a bean by annotating it with @Component and use ScreenBuilders in it (because Screens can be used only from inside a screen, not from a regular bean), or add ApplicationContextAware interface to your class and use ApplicationContext to get beans instead of injecting them.

See examples in the docs.

Regards,
Konstantin

Thanks Konstantin, my bad of course.

Full working solution for everybody’s perusal:

Class

package com.myapp.utils;

import io.jmix.core.security.CurrentAuthentication;
import io.jmix.securityui.screen.changepassword.ChangePasswordDialog;
import io.jmix.ui.AppUI;
import io.jmix.ui.ScreenBuilders;
import io.jmix.ui.screen.Screen;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("changeUserPasswordMenuBean")
public class ChangeUserPasswordMenu
{
	@Autowired
	private ScreenBuilders screenBuilders;

	@Autowired
	private CurrentAuthentication currentAuthentication;

	public void showChangePwdDialog() {

		final Screen frameOwner = AppUI.getCurrent().getTopLevelWindowNN().getFrameOwner();

		screenBuilders.screen(frameOwner)
			.withScreenClass(ChangePasswordDialog.class)
			.build()
			.withUsername(currentAuthentication.getUser().getUsername())
			.withCurrentPasswordRequired(true)
			.show();
	}

}

Menu item

<item bean="changeUserPasswordMenuBean" beanMethod="showChangePwdDialog" caption="msg://actions.changePassword" icon="LOCK"/>

Works like a charm.

Best,

J.

2 Likes

Hi guys,
this is great and thanks for that.
But in my case the “Item bean” is not working with Role designer and I cannot get it displayed. It is shown only for admin with fullAcess…
Any ideas?
Thank you.
T

@krivopustov @julius.ferianc

Hi @tomas.klems

You can do it manually.
Provided that you have the following menu item definition:

<item id="changePassword" bean="changeUserPasswordMenu" beanMethod="showChangePwdDialog"
      caption="Change password"/>

you should define the following role policies:

@ResourceRole(name = "UsersRole", code = "users-role")
public interface UsersRole {

    @MenuPolicy(menuIds = {"...", "changePassword"})
    @ScreenPolicy(screenIds = {"...", "ChangePasswordDialog"})
    void screens();
}

We have an issue for improving role designer: https://youtrack.jmix.io/issue/JST-1921/Add-the-ability-to-allow-access-to-a-bean-menu-item-for-a-role, will implement it in a future release.

Regards,
Konstantin