⚗️ Link multiple auth providers

This commit is contained in:
Liyas Thomas
2020-02-28 05:35:28 +05:30
parent 448c239f9f
commit 3bbe71f2c9
2 changed files with 292 additions and 31 deletions

View File

@@ -327,8 +327,7 @@ export default {
settings: {
SCROLL_INTO_ENABLED:
typeof this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED !==
"undefined"
typeof this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED !== "undefined"
? this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED
: true,
@@ -394,24 +393,6 @@ export default {
this.settings[key] = value
this.$store.commit("postwoman/applySetting", [key, value])
},
toggleSetting(key) {
this.settings[key] = !this.settings[key]
this.$store.commit("postwoman/applySetting", [key, this.settings[key]])
},
logout() {
fb.currentUser = null
firebase
.auth()
.signOut()
.catch(err => {
this.$toast.show(err.message || err, {
icon: "error",
})
})
this.$toast.info(this.$t("logged_out"), {
icon: "vpn_key",
})
},
signInWithGoogle() {
const provider = new firebase.auth.GoogleAuthProvider()
firebase
@@ -437,9 +418,74 @@ export default {
}
})
.catch(err => {
this.$toast.show(err.message || err, {
icon: "error",
})
// An error happened.
if (err.code === "auth/account-exists-with-different-credential") {
// Step 2.
// User's email already exists.
// The pending Google credential.
var pendingCred = err.credential
// The provider account's email address.
var email = err.email
// Get sign-in methods for this email.
auth.fetchSignInMethodsForEmail(email).then(function(methods) {
// Step 3.
// If the user has several sign-in methods,
// the first method in the list will be the "recommended" method to use.
if (methods[0] === "password") {
// Asks the user their password.
// In real scenario, you should handle this asynchronously.
var password = promptUserForPassword() // TODO: implement promptUserForPassword.
auth
.signInWithEmailAndPassword(email, password)
.then(function(user) {
// Step 4a.
return user.linkWithCredential(pendingCred)
})
.then(function() {
// Google account successfully linked to the existing Firebase user.
goToApp()
})
return
}
this.$toast.info(`${this.$t("login_with")}`, {
icon: "vpn_key",
duration: null,
closeOnSwipe: false,
action: {
text: this.$t("yes"),
onClick: (e, toastObject) => {
// All the other cases are external providers.
// Construct provider object for that provider.
// TODO: implement getProviderForProviderId.
var provider = new firebase.auth.GithubAuthProvider()
// At this point, you should let the user know that they already has an account
// but with a different provider, and let them validate the fact they want to
// sign in with this provider.
// Sign in to provider. Note: browsers usually block popup triggered asynchronously,
// so in real scenario you should ask the user to click on a "continue" button
// that will trigger the signInWithPopup.
auth.signInWithPopup(provider).then(function(result) {
// Remember that the user may have signed in with an account that has a different email
// address than the first one. This can happen as Firebase doesn't control the provider's
// sign in flow and the user is free to login using whichever account they own.
// Step 4b.
// Link to Google credential.
// As we have access to the pending credential, we can directly call the link method.
result.user
.linkAndRetrieveDataWithCredential(pendingCred)
.then(function(usercred) {
// Google account successfully linked to the existing Firebase user.
goToApp()
})
})
toastObject.remove()
},
},
})
})
}
})
},
signInWithGithub() {
@@ -466,11 +512,94 @@ export default {
})
}
})
.catch(err => {
// An error happened.
if (err.code === "auth/account-exists-with-different-credential") {
// Step 2.
// User's email already exists.
// The pending Google credential.
var pendingCred = err.credential
// The provider account's email address.
var email = err.email
// Get sign-in methods for this email.
auth.fetchSignInMethodsForEmail(email).then(function(methods) {
// Step 3.
// If the user has several sign-in methods,
// the first method in the list will be the "recommended" method to use.
if (methods[0] === "password") {
// Asks the user their password.
// In real scenario, you should handle this asynchronously.
var password = promptUserForPassword() // TODO: implement promptUserForPassword.
auth
.signInWithEmailAndPassword(email, password)
.then(function(user) {
// Step 4a.
return user.linkWithCredential(pendingCred)
})
.then(function() {
// Google account successfully linked to the existing Firebase user.
goToApp()
})
return
}
this.$toast.info(`${this.$t("login_with")}`, {
icon: "vpn_key",
duration: null,
closeOnSwipe: false,
action: {
text: this.$t("yes"),
onClick: (e, toastObject) => {
// All the other cases are external providers.
// Construct provider object for that provider.
// TODO: implement getProviderForProviderId.
var provider = new firebase.auth.GoogleAuthProvider()
// At this point, you should let the user know that they already has an account
// but with a different provider, and let them validate the fact they want to
// sign in with this provider.
// Sign in to provider. Note: browsers usually block popup triggered asynchronously,
// so in real scenario you should ask the user to click on a "continue" button
// that will trigger the signInWithPopup.
auth.signInWithPopup(provider).then(function(result) {
// Remember that the user may have signed in with an account that has a different email
// address than the first one. This can happen as Firebase doesn't control the provider's
// sign in flow and the user is free to login using whichever account they own.
// Step 4b.
// Link to Google credential.
// As we have access to the pending credential, we can directly call the link method.
result.user
.linkAndRetrieveDataWithCredential(pendingCred)
.then(function(usercred) {
// Google account successfully linked to the existing Firebase user.
goToApp()
})
})
toastObject.remove()
},
},
})
})
}
})
},
toggleSetting(key) {
this.settings[key] = !this.settings[key]
this.$store.commit("postwoman/applySetting", [key, this.settings[key]])
},
logout() {
fb.currentUser = null
firebase
.auth()
.signOut()
.catch(err => {
this.$toast.show(err.message || err, {
icon: "error",
})
})
this.$toast.info(this.$t("logged_out"), {
icon: "vpn_key",
})
},
toggleSettings(s, v) {
fb.writeSettings(s, !v)