Generate recover email link in firebase - javascript

Is there any way to create custom recoverEmail link in firebase/firebase-admin?
I've checked the docs and tutorials there's none.
Any help would be great!

From my understanding there is currently no solution for this within the SDK. Instead, we took the approach of using admin.auth().generateSignInWithEmailLink(email, actionCodeSettings) and then replacing the mode within the returned link from signIn to recoverEmail.
const updatedLink = link.replace('signIn', 'recoverEmail');
This allowed us to customise the auth handler action as suggested here Create the email action handler page in the Firbase documentation.
Now we are able to call on admin.auth().updateUser again to reset the email to it's previous, along with update across our databases, merchant and other services. You'll also need to add the original email to a query in the updatedLink too.
const linkWithOriginalEmail = updatedLink.concat(`&email=${email}`)
Hope that helps and if anyone has a better solution we'd love to discuss.

I´m not sure if I understand your problem correctly, but If your goal is to have a custom link in the automatic email sent by Firebase when someone changes his authentication email address with updateEmail then you can define a custom action url in the Firebase console e.g. https://example.com/__/auth/action in the Authentication section and add the following code to the defined url (ref. https://firebase.google.com/docs/auth/custom-email-handler).
function handleRecoverEmail(auth, actionCode, lang) {
// Localize the UI to the selected language as determined by the lang
// parameter.
var restoredEmail = null;
// Confirm the action code is valid.
auth.checkActionCode(actionCode).then(function(info) {
// Get the restored email address.
restoredEmail = info['data']['email'];
// Revert to the old email.
return auth.applyActionCode(actionCode);
}).then(function() {
// Account email reverted to restoredEmail
// TODO: Display a confirmation message to the user.
// You might also want to give the user the option to reset their password
// in case the account was compromised:
auth.sendPasswordResetEmail(restoredEmail).then(function() {
// Password reset confirmation sent. Ask user to check their email.
}).catch(function(error) {
// Error encountered while sending password reset code.
});
}).catch(function(error) {
// Invalid code.
});
}

Related

How to find original email redirect link from landing page for firebase email link sign in option

In firebase, in order to authenticate a use after they click an email link, firebase needs the original clicked email link.
Example
This link redirects you a few times, and brings you to the page needed (currently set to localhost for dev purposes)
Firebase will only accept the email link, and only for one test per email which makes it difficult to diagnose this.
I need a way to fetch the first link clicked (the email link) from the landing page.
I apolagise if this has been answered anywhere else but I tried several combinations of keywords that did not work
export default function Home() {
return (
<>
boilerplate
<button onClick={bigFunction}>Press me to check if the browser has the email saved</button>
</>
)
}
let signinwithemaillink = "https://ticketme.page.link/qbvQ"
function bigFunction()
{
console.log(window.location.href)
if (isSignInWithEmailLink(auth, signinwithemaillink)) {
// Additional state parameters can also be passed via URL.
// This can be used to continue the user's intended action before triggering
// the sign-in operation.
// Get the email if available. This should be available if the user completes
// the flow on the same device where they started it.
let email = window.localStorage.getItem('emailForSignIn');
if (!email) {
// User opened the link on a different device. To prevent session fixation
// attacks, ask the user to provide the associated email again. For example:
email = 'example#gmail.com';
}
// The client SDK will parse the code from the link for you.
signInWithEmailLink(auth, email, signinwithemaillink)
.then((result) => {
alert("all good")
console.log(result.user)
// Clear email from storage.
window.localStorage.removeItem('emailForSignIn');
// You can access the new user via result.user
// Additional user info profile not available via:
// result.additionalUserInfo.profile == null
// You can check if the user is new or existing:
// result.additionalUserInfo.isNewUser
})
.catch((error) => {
console.log(error.code)
// Some error occurred, you can inspect the code: error.code
// Common errors could be invalid email and invalid or expired OTPs.
});
}
}
As you can tell there is still an incredible amount of comments from the firebase docs, Im just trying to get this to work.
*Amended - I cut out the dynamic link, so the current redirect cycle is as follows:
Email -> Firebase Redirect Link -> Desired Page

Customize Stripe Checkout Form

I'm currently working on a stripe payment method inside my Angular application. By default, the stripe form has an 'email' input field of type 'email'. I wanted to change that input filed to 'Name' with the type 'text'. I've tried different methods but none really work Can somebody help me in this regard. Any help would very much appreciated. Thanks.
I'm Attaching a stripe form picture for further assistance.
MY Stripe method Implementation
loadStripe() {
console.log('loadStripe');
if (!window.document.getElementById('stripe-script')) {
let s = window.document.createElement('script');
s.id = 'stripe-script';
s.type = 'text/javascript';
s.src = 'https://checkout.stripe.com/checkout.js';
s.onload = () => {
console.log('token');
this.handler = (window as any).StripeCheckout.configure({
key: this.stripKey,
locale: 'auto',
token(token: any) {
// You can access the token ID with `token.id`.
// Get the token ID to your server-side code for use.
console.log('token', token);
alert('Payment Success!!');
}
});
};
window.document.body.appendChild(s);
}
}
Don't do this! Stripe Checkout is not supposed to be customized in this way and does not directly post data to your server but to Stripe's server. Whatever happens from when you bring up the Checkout panel to when they call you with a token is Stripe's web application, not yours, and may change at any time. If you try to change them, not only is your code prone to break from one day to another without warning, Stripe may detect it and think that the user's browser is running malware because you're not supposed to do that, and chances are attempting to change their UI is also a breach of contract.
If all you want to do is to pre-populate the email address with the one they've already written, you can pass it as the key email in the object passed to StripeCheckout.configure. But you're meant to collect all other information using your own form.
If you don't want to collect their email address and don't want Stripe Checkout to do so either, stop using Stripe Checkout and build your own form including credit card entry fields with Stripe Elements.

Firebase user's details change listener in Javascript

so if a user logs into your app, you can check that by
firebase.auth().onAuthStateChanged((user)=>{});
but if the user is already logged in and his user has a property change, how do you see that?
in my case, I have the user verify his email address and when done, he should be able to see a change instantly on his app after verifying his email. So I am using react native, which is pretty much javascript with ES6 syntax in it and I am doing a firebase.auth().onAuthStateChanged(); but its not working, I even have a button on the screen that checks if verified like this:
if (!firebase.auth().currentUser.emailVerified) { firebase.auth().currentUser.sendEmailVerification(); }
else if (firebase.auth().currentUser.emailVerified) { this.setState({ showVerifier: false }); }
but even that isn't working, as if the firebase.auth().currentUser doesn't update if the email is verified, what can be done here?
As far as I understand your question, I would like to give you an idea.
I think onAuthStateChanged() gets triggered only when your Auth State Changes (login, logout) and not when the user properties change.
As they have mentioned in the documentation,
Adds an observer for changes to the user's sign-in state. Prior to
4.0.0, this triggered the observer when users were signed in, signed out, or when the user's ID token changed in situations such as token
expiry or password change. After 4.0.0, the observer is only triggered
on sign-in or sign-out.
function isVerified(){
var user = firebase.auth().currentUser;
if(user != null){
var status = user.emailVerified;
if(status)
{
// Verified
}else{
// Not Verified
}
}
else{
// User didn't login!
}
}
So, you have to manually check it by defining a function like above and you can call this function when the user clicks the button
If you are using react-native-firebase (highly recommended, since it is supports the latest firebase features), you can listen on user changes as stated in this doc
From the doc
Adds a listener to observe changes to the User object. This is a superset of everything from auth#onAuthStateChanged, auth#onIdTokenChanged and user changes. The goal of this method is to provide easier listening to all user changes, such as when credentials are linked and unlinked, without manually having to call User#reload.
onUserChanged(listener: AuthListenerCallback): () => void;

Firebase - Check Password

I have a scenario that requires checking an entered password against the user's firebase password before the user does an irreversible task. This is different from creating an account or signing in. How can you check against a firebase password? It doesn't look like there's a password property in firebase.auth().currentUser.
Update:
The user must verify their password and the Delete button will run a function to check it. If it matches the firebase password, the Delete button will succeed in triggering a pretty modal to pop up.
I would suggest you to store the user password somewhere if you need to check against it at some point.
Instead of storing it inside your database (which wouldn't be safe) I would personally store it on user's device using UserDefaults so that you can access it easily whenever you need to perform your sensible tasks.
Update:
Another possibility would be using the reauthenticateWithCredential method. If the method return success then, perform your sensitive task. If it fails, ask your user to type the correct password.
As per your request, this is how you would reauthenticate the user using his email & password :
// First you get your current user using Auth :
let currentUser = Auth.auth()?.currentUser
// Then you build up your credential using the current user's current email and password :
let credential = EmailAuthProvider.credential(withEmail: email, password: password)
// use the reauthenticate method using the credential :
currentUser?.reauthenticate(with: credential, completion: { (error) in
guard error == nil else {
return
}
// If there is no error, you're good to go
// ...Do something interesting here
})
You can find some more explanation inside the Firebase documentation here : https://firebase.google.com/docs/auth/ios/manage-users

Updating rails model objects in Javascript

Okay.
Google API gives you the javascript for the Google Plus signup/login button.
function signinCallback(authResult) {
if (authResult['status']['signed_in']) {
// Update the app to reflect a signed in user
// Hide the sign-in button now that the user is authorized, for example:
document.getElementById('signinButton').setAttribute('style', 'display: none');
} else {
// Update the app to reflect a signed out user
// Possible error values:
// "user_signed_out" - User is signed-out
// "access_denied" - User denied access to your app
// "immediate_failed" - Could not automatically log in the user
console.log('Sign-in state: ' + authResult['error']);
}
}
IF a user successfully logs in with Google Plus, I want to use the form attributes/variables to create a new user. A user has a username and a password. The Google Plus login gives the google plus user a fullname and a gplus id. I want to create a user in the database with a username equal to their gplus fullname and a password equal to their gplus id. How would I go about using ruby with my javascript to save them to the model. I reviewed this link
Section four seems to be the right direction. I'm just having trouble grasping it.
If you think there would be a better way to do this. Please let me know! I read up on Devise with google plus, but it seemed too risky to implement during a time crunch. I might try it anyway depending on how long this takes me.

Categories

Resources