In such scenarios, Oracle APEX doesn't provide any out-of-box Reset Password option to users. So what's the workaround ? Well, we need to build a custom solution to have this feature.
Let's see how this can be achieved.
Pre-check:
Please navigate to Shared Components -> Authentication Schemes
Make sure the Current scheme is set to Oracle APEX Accounts
Please note that below solution works only for this scheme and won't be applicable to any other authentication options.
1. Page for entering Email ID where user can receive Reset Password URL:
- Create a new blank page. Let's number it 8001
- Create a Text Field and name it P8001_EMAIL
- Create a button and name it Submit
- Set Page Authentication to Public because user must be able to access it without limitation of any credentials
- Set Session State Protection for P8001_EMAIL to "Restricted - May not be set from browser"
This is to prevent possibility of URL Tampering. This way if the user tries to modify the URL in any way then it will give the error.
- If we run this page at this stage, it should look like this
2. Create a Link on seeded Login Page pointing to above Page :
- Now, let's create a link to this page on the actual login page
- Navigate to Page#9999 which is the standard login page in APEX
- Create a new button under Language Selector region and name it Reset Password
- Under Behavior section, set Action to Redirect to Page in this Application and Target to Page 8001
- If we run this page at this stage, it should look like this
3. Add logic on the newly create Email Page from Step 1:
- Navigate to Page#8001
- Now, let's create a Computation for this item
- Right click on P8001_USER_NAME and select Create Computation
- Create computation with below details
Point: After Submit
SQL Query:
SELECT USER_NAME
Item: P8001_EMAIL
3. Create a new Page to let user enter New Password
- Create a new blank page. Let's number it 8002
- Set Page Authentication to Public because user must be able to access it without limitation of any credentials
- Create a new Text Item named P8002_PASSWORD and set Type to Password
- Create a new button named Submit with Action as Submit Page
- Now, create a new item named P8002_USER_NAME and set type to Hidden and Disable Value Protected option
- Set Session State Protection to "Checksum Required - Application Level" under Security section.
This way if the user tries to modify the User Name value in URL in any way then it will give the error.
We are setting the checksum at application level as the same user may be having access to other applications and we want to limit this restriction for our application only.
4. Generate Reset Password Link and Email to User
- Navigate to Page#8001
- Create a new item named P8001_LINK and set type to Hidden
- Go to Processes and Create a new Process named Generate Link.
Here, we are essentially using GET_URL API to generate the link pointing to our App (Identified by :APP_ID), Page 8002 and we are passing user name as the parameter for the item :P8001_USER_NAME
PL/SQL Code:
DECLARE
Server-side Condition:
Type: Item is NOT NULL
Item: P8001_USER_NAME
- Create another process named Send Email with below details
Type: Send E-Mail
From: <From Email ID>
To: &P8001_EMAIL.
Subject: Reset Password
Body:
Please follow the below link to reset your Password:
Send Immediately: Yes
Server-side Condition:
Type: Item is NOT NULL
Item: P8001_USER_NAME
Ensure to check Send Immediately check-box. This is essentially like implicitly issuing APEX_MAIL.PUSH_QUEUE api which sends the email instantly.
More details on PUSH_QUEUE here.
Here, make sure to use the From Email Id based on the Email Delivery configuration done in OCI. Please refer to my previous blog post to understand how to do this configuration.
- Now, this page is ready so let's test it
- Run this page and enter a valid Email ID and click Submit
- We should receive the Reset Password email with the URL pointing to Page 8002 along with the User Name and Checksum passed via the URL
4. Update the Password for the user returning via above URL
- Navigate to Page#8002
- Create a new item P8002_DISP_USER on this page. This is to show the user name for whom the password it being reset.
- Set this item to Display Only
- In the Source, set Type to Item and Item to P8002_USER_NAME
- Set Session State for this item to Per Session
- If we run the page at this stage using the URL received in the email, then it should look like this. We should be able to see the User Name to whom the Email was set indicating that the password will be reset for this user.
- Now, let's create a new Process named Reset Password with below details
Language: PL/SQL
Code:
BEGIN
Success Message: Your password has been reset successfully.
Server-side Condition: Type: Item is NOT NULL
Item: P8002_USER_NAME
Important:
APEX_UTIL.RESET_PASSWORD API can be executed only by someone who has Admin Role.
Hence, the custom schema/user where this app resides must be granted 'APEX_ADMINISTRATOR_ROLE' role in order to be able to execute above code.
If this configuration is not done, then you will see errors on the page as Reset Password API will fail due to insufficient privileges.
- Now, let's create a Branch to page 9999 so that user is redirected to seeded Login Page upon resetting the password
- That's it ! The Reset Password page is ready. Let's test the same.
1. Page for entering Email ID where user can receive Reset Password URL:
- Create a new blank page. Let's number it 8001
- Create a Text Field and name it P8001_EMAIL
- Create a button and name it Submit
- Set Page Authentication to Public because user must be able to access it without limitation of any credentials
- Set Session State Protection for P8001_EMAIL to "Restricted - May not be set from browser"
This is to prevent possibility of URL Tampering. This way if the user tries to modify the URL in any way then it will give the error.
- If we run this page at this stage, it should look like this
2. Create a Link on seeded Login Page pointing to above Page :
- Now, let's create a link to this page on the actual login page
- Navigate to Page#9999 which is the standard login page in APEX
- Create a new button under Language Selector region and name it Reset Password
- Under Behavior section, set Action to Redirect to Page in this Application and Target to Page 8001
- If we run this page at this stage, it should look like this
3. Add logic on the newly create Email Page from Step 1:
- Navigate to Page#8001
- Now, let's fetch the User Name associated with this EMAIL ID as we need to use it in further steps
- Create a new item named P8001_USER_NAME and set the Type to Hidden
- Set Session State Protection for P8001_USER_NAME to "Restricted - May not be set from browser"
This is to prevent possibility of URL Tampering. This way if the user tries to modify the URL in any way then it will give the error.- Create a new item named P8001_USER_NAME and set the Type to Hidden
- Set Session State Protection for P8001_USER_NAME to "Restricted - May not be set from browser"
- Now, let's create a Computation for this item
- Right click on P8001_USER_NAME and select Create Computation
- Create computation with below details
Point: After Submit
SQL Query:
SELECT USER_NAME
FROM APEX_WORKSPACE_APEX_USERS
WHERE UPPER(EMAIL) = UPPER(:P8001_EMAIL);
Server-side Condition:
Type: Item is NOT NULLServer-side Condition:
Item: P8001_EMAIL
3. Create a new Page to let user enter New Password
- Create a new blank page. Let's number it 8002
- Set Page Authentication to Public because user must be able to access it without limitation of any credentials
- Create a new Text Item named P8002_PASSWORD and set Type to Password
- Set Session State Protection for P8002_PASSWORD to "Restricted - May not be set from browser"
This is to prevent possibility of URL Tampering. This way if the user tries to modify the URL in any way then it will give the error.- Create a new button named Submit with Action as Submit Page
- Now, create a new item named P8002_USER_NAME and set type to Hidden and Disable Value Protected option
- Set Session State Protection to "Checksum Required - Application Level" under Security section.
This way if the user tries to modify the User Name value in URL in any way then it will give the error.
We are setting the checksum at application level as the same user may be having access to other applications and we want to limit this restriction for our application only.
4. Generate Reset Password Link and Email to User
- Navigate to Page#8001
- Create a new item named P8001_LINK and set type to Hidden
- Go to Processes and Create a new Process named Generate Link.
Here, we are essentially using GET_URL API to generate the link pointing to our App (Identified by :APP_ID), Page 8002 and we are passing user name as the parameter for the item :P8001_USER_NAME
PL/SQL Code:
DECLARE
LV_LINK VARCHAR2(4000);
BEGIN
LV_LINK := APEX_PAGE.GET_URL(
P_APPLICATION => :APP_ID,
P_PAGE => 8002,
P_SESSION => NULL,
P_ITEMS => 'P8002_USER_NAME',
P_VALUES => :P8001_USER_NAME
);
:P8001_LINK := REPLACE(apex_mail.get_instance_url,'/ords/','') || LV_LINK;
EXCEPTION
WHEN OTHERS THEN NULL;
END;
Server-side Condition:
Type: Item is NOT NULL
Item: P8001_USER_NAME
- Create another process named Send Email with below details
Type: Send E-Mail
From: <From Email ID>
To: &P8001_EMAIL.
Subject: Reset Password
Body:
Please follow the below link to reset your Password:
&P8001_LINK.
Send Immediately: Yes
Server-side Condition:
Type: Item is NOT NULL
Item: P8001_USER_NAME
Ensure to check Send Immediately check-box. This is essentially like implicitly issuing APEX_MAIL.PUSH_QUEUE api which sends the email instantly.
More details on PUSH_QUEUE here.
Here, make sure to use the From Email Id based on the Email Delivery configuration done in OCI. Please refer to my previous blog post to understand how to do this configuration.
- Now, this page is ready so let's test it
- Run this page and enter a valid Email ID and click Submit
- We should receive the Reset Password email with the URL pointing to Page 8002 along with the User Name and Checksum passed via the URL
4. Update the Password for the user returning via above URL
- Navigate to Page#8002
- Create a new item P8002_DISP_USER on this page. This is to show the user name for whom the password it being reset.
- Set this item to Display Only
- In the Source, set Type to Item and Item to P8002_USER_NAME
- Set Session State for this item to Per Session
- If we run the page at this stage using the URL received in the email, then it should look like this. We should be able to see the User Name to whom the Email was set indicating that the password will be reset for this user.
- Now, let's create a new Process named Reset Password with below details
Language: PL/SQL
Code:
BEGIN
APEX_UTIL.RESET_PASSWORD(P_USER_NAME => UPPER(:P8002_USER_NAME),
P_OLD_PASSWORD => NULL,
P_NEW_PASSWORD => :P8002_PASSWORD,
P_CHANGE_PASSWORD_ON_FIRST_USE => FALSE
);
EXCEPTION
WHEN OTHERS THEN NULL;
END;
Success Message: Your password has been reset successfully.
Server-side Condition:
Item: P8002_USER_NAME
Important:
APEX_UTIL.RESET_PASSWORD API can be executed only by someone who has Admin Role.
Hence, the custom schema/user where this app resides must be granted 'APEX_ADMINISTRATOR_ROLE' role in order to be able to execute above code.
If this configuration is not done, then you will see errors on the page as Reset Password API will fail due to insufficient privileges.
- Now, let's create a Branch to page 9999 so that user is redirected to seeded Login Page upon resetting the password
- That's it ! The Reset Password page is ready. Let's test the same.
0 comments:
Post a Comment