onbeforeunload to rollback some actions - javascript

I have an onbeforeunload and it is working fine. However, I wanted a way to trigger my DB method to delete my existing item if the user choose to leave the page. How is it possible to detect the result as well as to trigger my DB method? My DB method is on the server-side.
Here is my javascript for the onbeforeunload:
var showMsg = true;
window.onbeforeunload = function () {
if (showMsg) {
return "You must publish your profile. Leaving this page will delete the profile information you have entered."
}
}

Related

How to pass post submit callback to authentication method

I'm implementing a user comments feature, and I'd like to allow users to start writing before asking for authentication to reduce UX friction.
The user flow would be:
The user clicks on the input field, and start typing.
Once done, the user clicks on the submit button, then the system will check if the user is authenticated.
(A) If the user is logged
in, then it will submit the content.
(B) If the user is not logged
in, open a login/signup modal.
(A) If the user has an account, they
choose login methods either email or social login. (B) If the user
is new, they signup for a new account with either email or a social
account.
Once the user is authenticated, the authentication modal will close, and the content will then be submitted. (the user does not need to click on the submit button once again)
I think this is a very common use case, but I cannot find anything on Stackoverflow, or on Google search.
I'm using React with Firebase authentication. My first attempt is to check every second if the user is authenticated.
const submit = async (data) => {
if (!isAuthenticated) {
setOpenAuthDialog(true);
while (!isAuthenticated)
await new Promise((resolve) => setTimeout(resolve, 1000));
}
setDoc(doc(firestore, "comments", postId), data);
setInputField("");
};
However, I don't feel this is the best practice, because it will continue to check even when the user abandons the authentication flow.
I think using callbacks might be the better approach, but the authentication modal and comments are sibling components. I'm not sure if passing the callback function to the sign-in methods is possible.
Please let me know if there is an any better approach to this problem.
One way to do it with callbacks could be:
const submit = async (data) => {
if (!isAuthenticated) {
setOpenAuthDialog(true);
setDataWaitingForSubmission(data)
return;
}
setDoc(doc(firestore, "comments", postId), data);
setInputField("");
}
// This is passed as callback to auth modal
const onAuthSuccess = () => {
if (dataWaitingForSubmission && isAuthenticated) {
submit(dataWaitingForSubmission)
}
}

Not able to get the record GUID in JavaScript code on save of Quick Create form

I'm facing a problem on the Save event of the Quick Create form for the Case entity. On Save event, I'm not able to get the record GUID in JavaScript code.
Our requirement is when the user clicks on Save button on Quick Create form of the Case, we would like to redirect the user to the newly created case record.
We have attached below Javascript function on save event of Quick Create form. This code works well on one of the 30-days trial instance, but it doesn't work well on the client development CRM instance.
setTimeout(function () {
var formContext = executionContext.getFormContext();
var caseId = formContext.data.entity.getId();
caseId = caseId.replace("{", "").replace("}", "");
var entityFormOptions = {};
entityFormOptions["entityName"] = "incident";
entityFormOptions["entityId"] = caseId;
Xrm.Navigation.openForm(entityFormOptions).then(
function (success) {
console.log(success);
},
function (error) {
console.log(error);
});
}, 1000);
Quick create form purpose is flyout data entry without going away from current form/record. The same QC form is being opened from different places like Dashboard, Subgrid, Main navigation too bar, Lookup, etc. and allow user to continue the ongoing stuff. Out of all these places - only from the Main navigation, after the save - system will prompt with a toast to navigate to that record or option to create another record. This is by design.
If you want to navigate to that record irrespective of the origin, you can try some scripts like yours but you are going to break the OOB pipeline flow. You may do some unsupported but it’s not recommended. I never tried it but you can add a function from onSave event, using eventArgs.preventDefault we can stop the OOB save, then open the Full Main form by prepopulating values from QC to Main form, then save it on form load.
Instead of all this pain, why not you open the Main form itself. :)

What is preferred way to show DOM elements conditioned on firebase authentication

I'm trying to build a small web-page where sign-in is controlled by Firebase Google Auth and is popped up with profile page. What is the secured and preferred way to show the profile page?
Currently I am using onAuthStateChanged to manipulate particular div which holds profile data when user is signed-in. If the user is not logged in I am using removeChild() method to remove that div from DOM and when logged in appendChild() adds back the div.
Supposing you're using firebase's native firebase.auth().onAuthStateChanged function
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
As well as firebase.auth().currentUser to check if the user is currently logged in or not.
In that case, it's perfectly fine to use removeChild and appendChild and they do not hold any security threats, as if a user is not logged, after a page refresh all of the information will vanish.
Here's a small firebase application that shows that when the connection to the firebase is closed and removeChild is used, appendChild stops working as firebase is disconnected, thus proving the point that it's safe to use.
https://jsfiddle.net/vh9xay6e/
Note that in this example I'm not testing any authentification, just the use of firebase with removeChild and appendChild.
You can see that once the connection to Firebase is over, nothing on the frontend side can happen to change that.
Using onAuthStateChanged method we can act upon state change (sign in or Sign out)
As an example :
firebase.auth().onAuthStateChanged(user=>{
if(user){
document.getElementById("id").classList.remove('hide')
//this will populate your class which associate with above id.
} else{
document.getElementById("id_of_your_div").classList.add('hide')
}
})
I think it's okay to use removeChild and appendChild method based on firebase auth state changes in your application.
try to wire around your code by:
var userCurrent = firebase.auth().currentUser; in a function.
NOTE: Make sure you need to be sure first you signed in (as its an async operation), followed by the update user data as:
var authenticationRef = firebase.auth();
authenticationRef.onAuthStateChanged(function(user) {
if (user) {
console.log('onAuthStateChanged : '+user.displayName);
_updateUser();
} else {
console.log('Not login');
}
});
fucntion _updateUser(){
var userCurrent = firebase.auth().currentUser;
userCurrent.updateProfile({
displayName: "Karthik.S",
}).then(function() {
var displayName = userCurrent.displayName;
}, function(error) {
});
}

Limit Only One Session Per User In ASP.NET Mvc 4

I am working on one web application in which i want to make sure that website allow only one login per user at a time.
when user login i am updating table column islogged=1 when logoff i am updating islogged =0
but the problem is when user session timeout or if user closing browser i am unable to capture this events.i am using sqlserver state to store sessions so Session_End event is not fired in this state .
it only works in InProc State. and also in browser close event i have tried onunload event. but this event is fired on tab closed also. not able to differentiate tab close and browser close.
i want only one concurrent user login. is there any other way to achieve this.
i am using this code to capture browser close event.
<body class="fixed-top" onclick="clicked=true;" onunload="CheckBrowser()">
<script type="text/javascript">
var clicked = false;
// var xmlHttp
// var browser = navigator.appName;
function CheckBrowser() {
debugger
// var browserClose = isUserClickedCloseButton();
if (clicked == false) {
$.ajax({
url: "#Url.Content("~/Account/LogOff")",
type: 'Post',
success: function (data) {
},
error: function () { alert("Error On Logut..."); }
});
}
alternatively you can store store session id in DB along with the current loggedin status as true or false. when user hits just check if loggedin flag is true and take the action needed
Please check the below links which has similar Q&A.
Only one concurrent login per user in Asp.net
Only one concurrent login per UserID in Asp.net

Picking up meteor.js user logout

Is there any way to pick up when a user logs out of the website? I need to do some clean up when they do so. Using the built-in meteor.js user accounts.
I'll be doing some validation using it, so I need a solution that cannot be trigger on behalf of other users on the client side - preferably something completely server side.
You may use Deps.autorun to setup a custom handler observing Meteor.userId() reactive variable changes.
Meteor.userId() (and Meteor.user()) are reactive variables returning respectively the currently logged in userId (null if none) and the corresponding user document (record) in the Meteor.users collection.
As a consequence one can track signing in/out of a Meteor application by reacting to the modification of those reactive data sources.
client/main.js :
var lastUser=null;
Meteor.startup(function(){
Deps.autorun(function(){
var userId=Meteor.userId();
if(userId){
console.log(userId+" connected");
// do something with Meteor.user()
}
else if(lastUser){
console.log(lastUser._id+" disconnected");
// can't use Meteor.user() anymore
// do something with lastUser (read-only !)
Meteor.call("userDisconnected",lastUser._id);
}
lastUser=Meteor.user();
});
});
In this code sample, I'm setting up a source file local variable (lastUser) to keep track of the last user that was logged in the application.
Then in Meteor.startup, I use Deps.autorun to setup a reactive context (code that will get re-executed whenever one of the reactive data sources accessed is modified).
This reactive context tracks Meteor.userId() variation and reacts accordingly.
In the deconnection code, you can't use Meteor.user() but if you want to access the last user document you can use the lastUser variable.
You can call a server method with the lastUser._id as argument if you want to modify the document after logging out.
server/server.js
Meteor.methods({
userDisconnected:function(userId){
check(userId,String);
var user=Meteor.users.findOne(userId);
// do something with user (read-write)
}
});
Be aware though that malicious clients can call this server method with anyone userId, so you shouldn't do anything critical unless you setup some verification code.
Use the user-status package that I've created: https://github.com/mizzao/meteor-user-status. This is completely server-side.
See the docs for usage, but you can attach an event handler to a session logout:
UserStatus.events.on "connectionLogout", (fields) ->
console.log(fields.userId + " with connection " + fields.connectionId + " logged out")
Note that a user can be logged in from different places at once with multiple sessions. This smart package detects all of them as well as whether the user is online at all. For more information or to implement your own method, check out the code.
Currently the package doesn't distinguish between browser window closes and logouts, and treats them as the same.
We had a similar, though not exact requirement. We wanted to do a bit of clean up on the client when they signed out. We did it by hijacking Meteor.logout:
if (Meteor.isClient) {
var _logout = Meteor.logout;
Meteor.logout = function customLogout() {
// Do your thing here
_logout.apply(Meteor, arguments);
}
}
The answer provided by #saimeunt looks about right, but it is a bit fluffy for what I needed. Instead I went with a very simple approach like this:
if (Meteor.isClient) {
Deps.autorun(function () {
if(!Meteor.userId())
{
Session.set('store', null);
}
});
}
This is however triggered during a page load if the user has not yet logged in, which might be undesirable. So you could go with something like this instead:
if (Meteor.isClient) {
var userWasLoggedIn = false;
Deps.autorun(function (c) {
if(!Meteor.userId())
{
if(userWasLoggedIn)
{
console.log('Clean up');
Session.set('store', null);
}
}
else
{
userWasLoggedIn = true;
}
});
}
None of the solutions worked for me, since they all suffered from the problem of not being able to distinguish between manual logout by the user vs. browser page reload/close.
I'm now going with a hack, but at least it works (as long as you don't provide any other means of logging out than the default accounts-ui buttons):
Template._loginButtons.events({
'click #login-buttons-logout': function(ev) {
console.log("manual log out");
// do stuff
}
});
You can use the following Meteor.logout - http://docs.meteor.com/#meteor_logout

Categories

Resources