Last Updated: Dec 2, 2024
Overview
To increase security, and in cases where the user is pre-created, it sometimes helps to force the user to reset their password on their first login attempt. This can be achieved only by leveraging Extensibility tools > Actions.
Applies To
- Change Password
- First Login
- Actions
Solution
To achieve this, a combination of two actions in Auth0 can be created: a post-login action and a post-change password action.
Post-Login Action:
// Post-login action to force password reset on first login
exports.onExecutePostLogin = async (event, api) => {
// Check the login count to determine if it's the user's first login
const loginCount = event.stats.logins_count;
if (loginCount === 1) {
// Set the needsPasswordReset flag to true for the user's first login
await api.user.setAppMetadata(event.user.user_id, { needsPasswordReset: true });
// Deny access and prompt the user to reset their password
api.access.deny(`Please reset your password!`);
} else {
// For subsequent logins, retrieve user data to check if password reset is required
// Check if the needsPasswordReset flag exists and is set to true
if (userData.app_metadata.needsPasswordReset === true) {
// If the flag is true, deny access and prompt the user to reset their password
api.access.deny(`Please reset your password!`);
}
// If the flag exists and is set to false, do nothing
}
};
This first Action is responsible for checking the logic of when the user is allowed or is not allowed to enter the application based on the needsPasswordReset flag that is either true or false.
Post-Change Password Action:
// Post Change Password Action to update user metadata using the management api
exports.onExecutePostChangePassword = async (event) => {
const ManagementClient = require('auth0').ManagementClient;
const management = new ManagementClient({
domain: yourAuth0Domain,
clientId: M2M_Client_ID,
clientSecret: M2M_Client_Secret,
scope: 'read:users update:users',
});
try {
// Update the needsPasswordReset flag to false after password reset
await management.updateAppMetadata({ id: event.user.user_id }, { needsPasswordReset: false });
} catch (error) {
console.error('An error occurred while updating user metadata:', error);
}
};
This Post-Change Password Action is responsible for using the management API and changing the user’s metadata flag value after they change their password to allow them to log in from this point forward.
The use of the Management API in Actions is documented in How can I use the Management API in Actions?
This combination of actions ensures that new users are prompted to reset their password on their first login, enhancing the security of the application.
The second option is to leverage the Forms feature to accomplish this. Here is a basic example of what this implementation would look like:
The step node is used to obtain the new password value from the user and then the flow node is to update the metadata with the new password. Here are the details from the step node:
In this example, the Field ID is “password”, but this can really be any name.
What is important here is passing this field value to the flow node for the password to be updated. The flow node should be configured like so:
{{fields.ID}} in the body of the request should be modified to match the ID from the step node. The form is now ready to be published.
Once published, the form needs to be rendered using a Post Login action. Here is an example of using the login count to determine if this is a new user:
exports.onExecutePostLogin = async (event, api) => {
const FORM_ID = 'ENTER FORM ID HERE';
const loginCount = event.stats.logins_count;
if (loginCount === 1) {
api.prompt.render(FORM_ID);
}
}
exports.onContinuePostLogin = async (event, api) => {}
After the password is changed, the user is logged in and the tenant logs will also confirm that the password was changed.