ORACLE APEX: How do I prevent reloading of the login page when I use submit page action? - plsql

They request me that when a common user logs in, I must validate user and password for access to the system but when user is admin, I must validate user, password and a token that the system send to email user's (2FA).
I have created a process that handles:
-validate if the username and password are correct
-Obtains the type of user, if it is a common user it redirects him to the first page, otherwise it sends a token to his email.
PROCEDURE PRC_PROCESA_LOGIN(p_username VARCHAR2, p_password VARCHAR2, p_app_id NUMBER, p_ip_cliente VARCHAR2) IS
l_rt_autenticacion_resultado rt_autenticacion_resultado;
l_enable_2fa number;
l_tipo_usuario VARCHAR2(1);
e_error exception;
BEGIN
l_rt_autenticacion_resultado := pkg_eir_seguridad_2.FNC_AUTENTICAR_USUARIO(p_username, p_password, p_ip_cliente);
SELECT SC.Enable_2fa INTO l_enable_2fa FROM OF_SERVER_CONFIG SC;
IF l_rt_autenticacion_resultado.exito THEN
SELECT tipo_usuario
INTO l_tipo_usuario
FROM of_usuario u
WHERE u.cod_usuario =
l_rt_autenticacion_resultado.usuario_autenticado_id;
IF (l_enable_2fa = 1 AND l_tipo_usuario = 'B') THEN
l_rt_autenticacion_resultado.exito := FNC_GENERAR_TOKEN_2AF(p_username, p_password);
IF l_rt_autenticacion_resultado.exito = TRUE THEN
apex_util.set_session_state('APP_2FA', 1);
END IF;
ELSE
apex_util.set_session_state('APP_USUARIO_AUTENTICADO_ID', l_rt_autenticacion_resultado.usuario_autenticado_id);
Wwv_Flow_Custom_Auth_Std.Post_Login(p_username,
p_password,
v('APP_SESSION'),
p_App_Id || ':1');
END IF;
ELSE
apex_util.set_session_state('APP_AUTENTICACION_RESULTADO_MENSAJE',
l_rt_autenticacion_resultado.mensaje);
apex_util.set_custom_auth_status(l_rt_autenticacion_resultado.mensaje);
--raise_application_error(-20001, l_rt_autenticacion_resultado.mensaje);
END IF;
END;
I have created an AD event type: click, action: Execute Server-side code and place the procedure
I tried with a common user but when I click the LOGIN button, it does not perform the redirection
I have created an AD LOGIN button:
event: click,
action: Execute Server-side code
PL/SQL Code:
begin
PKG_EIR_SEGURIDAD.PRC_PROCESA_LOGIN(p_username => :P9999_USERNAME,
p_password => to_char(:P9999_PASSWORD),
p_app_id => :APP_ID,
p_ip_cliente => owa_util.get_cgi_env ('REMOTE_ADDR'));
end;
I tried with a common user but when I click the LOGIN button it does not perform the redirection.
I have placed this same procedure in Processing. I tried with the same common user and if it redirects it to the home page.
button login:
-Behavior accion: Submit page
Processing:
-Processes Name: Login
-Type: Execute Code
-PL/SQL: (same code above)
My problem is that when I try with an administrator user the page is reloaded and deletes the credentials that the user I had already entered. My idea is that when the user is an administrator, the process returns false but leaves the values, then through an AD enable the 2FA region that has the item P9999_TOKEN and the VALIDATE button. When the user enters the token and clicks on the VALIDATE button, this must call a procedure that validates
that the token is correct and redirects it to the home page.
How could I solve this problem or what should I do to find a solution?

Here is one option. I have not verified it with a custom authentication script but you should be able to fill in the blanks. The idea is to do it all in the login page and not in the authentication procedure and also not to submit the login page until token is verified. reloading the login page with the entered value could be a security issue.
On the login page:
add 2 additional page items: P9999_TOKEN (text field) and P9999_TOKEN_NEEDED (hidden, value protected)
add a dynamic action (DA) on page load to hide P9999_TOKEN
add a dynamic action on change of P9999_USERNAME
add true action of type serverside code (items to return P9999_TOKEN_NEEDED) to check if the user needs to enter the token. Set the value to Y or N depending on the outcome. If the outcome is Y, then send the token value email in this pl/sql block - you know who the user is.
add a true action to show the P9999_TOKEN (client condition javascript expression, apex.item('P9999_TOKEN_NEEDED').getValue() == 'Y'
add a validation with serverside conditon item = value, P9999_TOKEN_NEEDED = Y to validate the token. If the token is invalid, validation fails and the page is not submitted so user never logs on.

Related

ASP.NET Identity rollback unverified email change

At the moment this is a general question with no code as I am looking for a BEST practices example to my question:
User issues an email change request. (done)
A link is sent to the new address to confirm the new email. (done)
User clicks the confirmation link and the DB update is complete. (done)
What also needs to happen is when the confirmation link is sent for the change, an email should also be sent to the original email address where the user can click a link to reverse the process for whatever reason. I would think also that even if the new email address was accepted, if the original link denies the change it reverts and 2) if the original email reverts and then the new email link is confirmed, that the request would then be denied.
Any direction or code on this matter would be greatly appreciated.
Seems like a simple bit field in the database user record would suffice, or an associated database record would work too. When both emails are sent, mark the field for that user, let's call it "ChangeEmailSent" to 1. When either email is clicked, the field should be updated to 0. The actual changing of the email should only occur if the field is 1.
Some pseudo-code if you like
private void CancelEmailChange(email)
{
var user = Database.GetUser(email);
user.ChangeEmailSent = false;
Database.Save();
}
private void ProcessEmailChange(email)
{
var user = Database.GetUser(email);
if (user.ChangeEmailSent)
{
user.email = getNewEmailAddress(); //whatever logic for a new email
user.ChangeEmailSent = false;
Database.Save();
}
}

How to show / validate error of a node listing page

i am trying to save form state in database and want to view in a listing page with its error validation.
i.e, i want to validate a previously saved form state from my database.
this is a node type form .
i had already tried node_validate its not working because i fetch the data before submitting the node . so there is no nid and for that it is not working
and also tried drupal_validate_form but it is showing
[form_token] => The form has become outdated. Copy any unsaved work in the form below and then reload this page
EDIT
Any one with any help , "How to save a form inputs in data base and retrive it from database with out form submision.
Thank You In advance
Any help is most Appreciable.
If you look in Drupal Core, you see this in includes/form.inc at the drupal_validate_form function:
if (isset($form['#token'])) {
if (!drupal_valid_token($form_state['values']['form_token'], $form['#token'])) {
$path = current_path();
$query = drupal_get_query_parameters();
$url = url($path, array('query' => $query));
// Setting this error will cause the form to fail validation.
form_set_error('form_token', t('The form has become outdated. Copy any unsaved work in the form below and then reload this page.', array('#link' => $url)));
// Stop here and don't run any further validation handlers, because they
// could invoke non-safe operations which opens the door for CSRF
// vulnerabilities.
$validated_forms[$form_id] = TRUE;
return;
}
}`
This shows that the "form has become outdated" message is being set here. So, you can make the isset($form[#token']) condition false by unsetting #token to prevent this message from appearing.
All you have to do is load the form state you're going to validate, and call
unset($form[#token']); before you call drupal_validate_form.

Meteor: Appending data to a users profile

I'm creating new users with the following:
Accounts.createUser({
username: t.find('#username').value,
password: t.find('#password').value,
email: t.find('#email').value,
profile : {
name: t.find('#name').value,
division: 'none',
enrolled: 'false'
}
});
I need to be able to update the division field when a user choose from a drop down select. This is my template:
<template name="userProfile">
<p>Select your division</p>
<select id="division">
<option>Div1</option>
<option>Div2</option>
<option>Div3</option>
<option>Div4</option>
</select>
<button id="enrolled"> Not enrolled </button>
<p>a: {{currentUser.profile.name}}</p>
<p>b: {{currentUser.profile.division}}</p>
</template>
I have a click event which works, but what I can't figure out is how to append or modify fields in the profiles:
Template.userProfile.events({
'click #division': function(e, t) {
console.log('Selected division is: ', t.find('#division').value);
Meteor.user.profile.division = t.find('#division').value;
},
'click: #enrolled': function(e, t) {
console.log('User is enrolled? : ');
}
});
What I'd like to happen is when a user chooses a division the field in the currentUser's profile gets updated.
I have one more question but I'll put that in a separate thread.
Thanks.
The code shown will only update a local copy.
To make a permanent change requires a database write to the users collection.
Per the documentation for Meteor.users:
Users are by default allowed to specify their own profile field with
Accounts.createUser and modify it with Meteor.users.update. To allow
users to edit additional fields, use Meteor.users.allow.
If you can't get that working on the client, it is probably a matter of permissions which are enforced on the client and not on the server. Meteor.allow() specifies these permissions on the client, and anything is permitted on the server.
Exploiting that latter fact, another way to implement profile or user information updates is to use remote methods where Meteor.call() on the client sends information to be executed on the server in a function specified in Meteor.Methods(). The server function that you write and put in Meteor.Methods would then test the validity of the update according to any conditions that you might want to defined, and if valid, call Meteor.users.update() with the update to the profile.

How to generate new Meteor login tokens (server side) in order to make a quick login link

Meteor has a loginWithToken method, and there are resume tokens in the user object. So one can login using one of these tokens with loginWithToken. That works.
Is there a way to generate new login tokens, or should I just use the resume tokens to create a quick login link?
As Johnny said, you can use the Accounts._generateStampedLoginToken() function, which is actually nothing special, just the following function:
_generateStampedLoginToken = function () {
return {
token: Random.secret(),
when: new Date
};
}
anyway, to use it, here is an example:
// Server //
// Creates a stamped login token
var stampedLoginToken = Accounts._generateStampedLoginToken();
/**
* Hashes the stamped login token and inserts the stamped login token
* to the user with the id specified, adds it to the field
* services.resume.loginTokens.$.hashedToken.
* (you can use Accounts._hashLoginToken(stampedLoginToken.token)
* to get the same token that gets inserted)
*/
Accounts._insertLoginToken(user._id, stampedLoginToken);
// Client //
// Login with the stamped loginToken's token
Meteor.loginWithToken(stampedLoginToken.token);
Yes, you can generate new tokens by calling Accounts._generateStampedLoginToken(). You can call it from within a login handler.
https://github.com/meteor/meteor/blob/master/packages/accounts-base/accounts_server.js#L114
it's 2015 - use one of these packages:
poetic:accounts-passwordless
acemtp:accounts-passwordless
http://fastosphere.meteor.com/?q=passwordless

Show a loader during the user log in process

I'm using the Accounts API to manage users. My app first tries to log in a user using their credentials, and in case that results in an error, it creates a new user account using the input credentials.
// Log the user in
Meteor.loginWithPassword(username, token, function(error) {
if(error) { // create a new user account, log them in and show the page
Accounts.createUser({
username: username,
email: username + '#example.com',
password: token,
profile: {name: username}
}, showThePage);
}
else { // show the page
//showThePage();
window.location.reload();
}
});
But this code block executes only when the user was previously logged out from their browser, and if that is the case it takes 2-3 seconds for Meteor to log the user in using loginWithPassword. As I'm using v0.5.0, there is no Meteor.loggingIn(), and the only thing I have is Meteor.userLoaded(). Meteor, for some reason, performs the login operation twice -- once by loading a placeholder user (that has only its userId property set) and again by loading the actual user. This makes userLoaded() return true twice, because of which my loader image doesn't work as expected.
Also notice that in the else block inside loginWithPassword, I'm doing a window reload. I've a function showThePage() which contains all the template data & event binding code. That function retrieves data using the username of the logged in user. Now because when that function in else block executes there isn't a real user logged in (remember meteor takes time to log the user in), no data gets fetched.
Is there a workaround for this problem?
First of all Meteor.userLoaded goes away after you upgrade beyond 0.5.0. You should check if Meteor.userId() === null to know if the user login has completed, which works in 0.5.0 and beyond. It may get called multiple times, as you have noted, but only when it has a real value has the login completed.
If you really can't update to 0.5.1, use a session variable to store loggingIn in between the call to loginWithPassword and the callback.
Session.set('loggingIn',true);
Meteor.loginWithPassword(...
Session.set('loggingIn',false);
});
Then, use the Session.get('loggingIn') call where appropriate.
Want to adapt userLoaded() instead?
var userLoadedTimes = 0; // can't use session variable because it would mess up reactive context on increments
Session.set('loggingIn',false);
Meteor.autorun(function () {
var userLoaded = Meteor.userLoaded(); // reactive.
if (userLoaded)
userLoadedTimes++;
if ((userLoadedTimes % 2 == 0) && (userLoadedTimes != 0))
Session.set('loggingIn',true);
else
Session.set('loggingIn',false);
});
What's that modulo doing there? Well if userLoaded has called a reactive context twice for some reason, you have actually logged in. So we check if userLoadedTimes is a multiple of two/even. All other times, i.e., when userLoadedTimes is odd (userLoadedTimes % 2 == 1), we're looking at the fake user... which means we're still loading the real user!
If this doesn't work, apply the even/odd logic to the first solution using session variable changes on the callback, in the event Meteor calls the loginWithPassword callback twice.

Resources