Firebase verify and reset password without sending separate mails - javascript

As part of offline user creation, I wanted to create an account from my back-end server and send out verification mail to user.
But when user clicks on the verification link, I also want to present a screen to set his password.
In the existing web-app, I have individual flows to handle verify and reset-password. but they are separate flows.
From the following doc
I could see that there is a parameter called mode to identify the action. Using this we are currently handling the verify and reset-password actions.
But is there a way to have a custom mode or some means to identify that the user has to be taken to a different screen after verification.
One workaround I can think of is to use the continueUrl (may be with a custom scheme). Not sure if this will work flawlessly.
Can somebody share their thoughts on this.

Using the continueUrl is indeed the correct way. Based on the mode you can decide which action is to be treated and then you can redirect to the continueUrl after the user has executed the corresponding action.
For example, the documentation you refer to shows the following example (note the // TODO: If a continue URL is available... comment):
function handleVerifyEmail(auth, actionCode, continueUrl, lang) {
// Localize the UI to the selected language as determined by the lang
// parameter.
// Try to apply the email verification code.
auth.applyActionCode(actionCode).then(function(resp) {
// Email address has been verified.
// TODO: Display a confirmation message to the user.
// You could also provide the user with a link back to the app.
// TODO: If a continue URL is available, display a button which on
// click redirects the user back to the app via continueUrl with
// additional state determined from that URL's parameters.
}).catch(function(error) {
// Code is invalid or expired. Ask the user to verify their email address
// again.
});
}

Related

How to revoke Identity API Token ( Chrome Extension )

I would like to add a Sign In with Google and a Sign Out button to my Chrome extension.
One technique that uses chrome.identity.getAuthToken for Sign In is described in this tutorial. It works great! When the button is clicked, it shows a popup for authentication and authorization.
But how should I implement the Sign Out button?
I tried to use the removeCachedAuthToken method in the on-click handler of my Sign Out button. With this, the sign-in functionality doesn't work as expected. After, when I pressed the Sign In button again, I got a new token directly without a popup asking the user to authenticate and authorize my extension. I would like users to be able to change their account by signing out. With this technique, that's not possible. How should I implement the sign out functionality to allow for this?
This has been bugging me too, until I realized that I got mixed up by the difference between sign-in and authorization, sign-out and revoking access.
First, let's not get caught up in the name of the button. Yo may call it Sign Out, but what you actually want to achieve is to let users revoke access for their Google Account, and then log in and grant access to a different account.
If you use removeCacheAuthToken, then authorize again, and see no popup, then that means the extension still has access to certain APIs. To check which apps have been granted access to which Google services, go to permission settings and have a look.
There are several ways to revoke access:
Go to chrome://identity-internals/ and remove the tokens that you want. Then click on the Authorize button, and you should see a popup to choose the Google accounts to grant access.
Of course, that method is for testing only. Your end users won't see the access token for your extension if they visit that page.
When the user clicks on the Revoke access button, or whatever name you call, display a popup that tells them to go to the permission settings page to manually revoke access.
Create a form on the current web page, add access token to the form and submits to the https://oauth2.googleapis.com/revoke endpoint.
From my experience, method 3 seems like an ideal solution, but it was a hit and mix for me. Sometimes I would get an invalid or expired token error, and troubleshooting it is not worth it. I would stick with method for peace of mind.
As mentioned in this answer, you can use https://accounts.google.com/o/oauth2/revoke?token=" + current_token) to allow the user to revoke access to the api.
Below is the function for the same:
function revokeToken() {
user_info_div.innerHTML = "";
chrome.identity.getAuthToken({ interactive: false },
function (current_token) {
if (!chrome.runtime.lastError) {
// #corecode_begin removeAndRevokeAuthToken
// #corecode_begin removeCachedAuthToken
// Remove the local cached token
chrome.identity.removeCachedAuthToken({token: current_token}, function(){});
// #corecode_end removeCachedAuthToken
// Make a request to revoke token in the server
var xhr = new XMLHttpRequest();
xhr.open(
"GET",
"https://accounts.google.com/o/oauth2/revoke?token=" + current_token);
xhr.send();
// #corecode_end removeAndRevokeAuthToken
// Update the user interface accordingly
changeState(STATE_START);
sampleSupport.log("Token revoked and removed from cache. " +
"Check chrome://identity-internals to confirm.");
}
});
}

Firebase: SIgn in/up via GitHub using the same button

I want to allow users to sign in/up via GitHub using firebase by clicking on the same button.
I create a new authentication for every user in the server side.
With the little piece of code, I'm able to detect if either the user is new or not:
const provider = new firebase.auth.GithubAuthProvider();
firebase.auth().signInWithPopup(provider).then((result) => {
if (result.additionalUserInfo.isNewUser) {
// The user is new
} else {
// The user is old
}
But, when the function signInWithPopup is called, if the user is a new user, a new authentication is automatically created for him. How can I avoid this?
And if the user is already authenticate, how can the user sign in from the client side? Where is the link between the authentication done from the back end with the user that wants to sign in the front end?
This is not how OAuth works. If you use an authentication provider like GitHub, they handle auth flow for you. The only thing that you are left with on the frontend side is an idToken with your identity, basic profile info, and a signature so you can as a user using this token. There's no distinction between sign up/sign in actions.
As you have noticed, Firebase is an extra layer in this flow, it creates an account for a user who signs in for the first time. But there's no user limit or extra payment so I wouldn't bother too much about these extra accounts. You might consider periodical cleanups if you care about the security here.
If you want to actually check if the user exists you have to use firebase-admin e.g. in a Firebase Function before the signInWithPopup is called. But still, unless you want to prevent users from signing up, you can hook your server logic into functions.auth.user().onCreate trigger.
To answer your last question, when the user is already signed in, you'll get the user object in firebase.auth().onAuthStateChanged when a page is loaded. Login state is stored by Firebase.js so once you have called signInWithPopup, you don't need extra steps.

Firebase RememberMe functionality

My webapp allows different users to login in different tabs/browsers on the same machine with different credentials (using signInWithEmailAndPassword). I achieve this by calling firebase.initializeApp(config, 'appName'+new Date().getTime()) for each login
When the user closes the tab or reloads (in window.onbeforeunload) I call .auth().signOut() to log him out.
I now want to add a RemeberMe functionality to my app page, that is a tickbox that if (and only if) ticked, will allow following logins from the same machine and username without giving the password even if the machine was for example restarted in the meantime.
How can that be achieved ?
what I am thinking about is (when remember me is on) to generate a token on the client stored in a cookie and maintain a table on the db which links tokens to passwords, there are two problems with this, first of all the password is saved as is on the db which is bad and second the password needs to be sent back to the client which is also bad.
any better options ?
Starting with Firebase JS 4.2.0 you can now specify session persistence. You can login different users in multiple tabs by calling:
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION)
And when the window is closed, the session is cleared.
For more on this, check https://firebase.google.com/support/release-notes/js#4.2.0 and https://firebase.google.com/docs/auth/web/auth-state-persistence
Just add a rememberMe checkbox to your login form with a reference variable(for an exmaple remember) and use firebase setPersistence like this,
firebase.auth().setPersistence(this.remember.checked ? fireauth.Auth.Persistence.LOCAL : fireauth.Auth.Persistence.SESSION)
(here I have used javaScript for the example)

Signing out doesn't change wl_auth cookie value in onedrive?

I followed the Javascript in Interactive Live SDK to enable Onedrive in My Web App and it's working fine.
But, following the above method sets a wl_auth cookie in the specified redirect domain. which contains the details of the user who was signed in during the time.
When I sign out the user and sign in with a different account the value of the old cookie still remains and I was only able to attach files from the old user not the new account. I have to follow the tedious process of deleting the cookies everytime to sign n a new user.
I have seen a Javascript method to subscribe to a logout event in Microsoft account. It is called WL.Event.subscribe. And I attach the following code to subscribe to a logout event,
WL.Event.subscribe("auth.logout", onLogout);
function onLogout() {
WL.logout();
}
I try Logging out of my old account and logged in with different account . still the problem persists. why?
Any help is kindly appreciated. Thank you!
Note: I don't have signin button in my Web app. When the User clicks "Attach from Onedrive" button for the first time they will be asked for sign in information. if they are signed in already they will be redirected to the Onedrive file Picker(till the cookie doesn't expire).
Are you using a custom signin button or are you using the signin button in WL.ui? If you're using the WL.ui signin button, it should clear the cookies when the user clicks the sign out button. The function that you provided above will only sign the user out after they have signed out. You might want to change the event to "auth.statusChange" and call WL.getLoginStatus to see what it is returning.

Vaildate user by label value

I am validating my users with header variables that I display in my .net application and my question is how can I validate that the user that is on the on the current page is allowed to proceed to any other pages.
I want to check the name from an array or names and if they are not listen then it will redirect them to an error page letting them know they do not have access.
I was going to take the path of sql authentication but that would just require an additional login page and since I already check the header variables I thought I could just go about this way. Any help regarding this would be great!
You should never trust ANY data sent from the client to your server. The header-variables can easily be modified to represent anything. One could easily forge the header to spoof themself for being somebody else (like admin in worst case).
You should really consider some sort of authentication that requires a combination of username + password, I'm afraid.
If you REALLY want to rely on the headers though, add a header that identifies themself, like X-USERNAME:CSharpDev4Evr, and then just parse that one and match against the array on back-end.
I don't know any C#.NET, but here's a JavaScript-snippet showing the principle:
var headerUsername = "CSharpDev4Evr";
var validUsernames = ["Eric", "CSharpDev4Evr", "Stackoverflow", "root"];
// Check if we are in the array
// Re-direct if we're not
if (validUsernames.indexOf(headerUsername) === -1)
window.location = 'error.html';
// Proceed with other authenticated stuff here
// ...

Categories