⚗️ 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

@@ -66,8 +66,9 @@ export default {
action: { action: {
text: this.$t("yes"), text: this.$t("yes"),
onClick: (e, toastObject) => { onClick: (e, toastObject) => {
fb.writeSettings("syncHistory", false) fb.writeSettings("syncHistory", true)
fb.writeSettings("syncCollections", true) fb.writeSettings("syncCollections", true)
fb.writeSettings("syncEnvironments", true)
this.$router.push({ path: "/settings" }) this.$router.push({ path: "/settings" })
toastObject.remove() toastObject.remove()
}, },
@@ -76,9 +77,74 @@ export default {
} }
}) })
.catch(err => { .catch(err => {
this.$toast.show(err.message || err, { // An error happened.
icon: "error", 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() { signInWithGithub() {
@@ -95,8 +161,9 @@ export default {
action: { action: {
text: this.$t("yes"), text: this.$t("yes"),
onClick: (e, toastObject) => { onClick: (e, toastObject) => {
fb.writeSettings("syncHistory", false) fb.writeSettings("syncHistory", true)
fb.writeSettings("syncCollections", true) fb.writeSettings("syncCollections", true)
fb.writeSettings("syncEnvironments", true)
this.$router.push({ path: "/settings" }) this.$router.push({ path: "/settings" })
toastObject.remove() toastObject.remove()
}, },
@@ -105,9 +172,74 @@ export default {
} }
}) })
.catch(err => { .catch(err => {
this.$toast.show(err.message || err, { // An error happened.
icon: "error", 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()
},
},
})
})
}
}) })
}, },
}, },

View File

@@ -327,8 +327,7 @@ export default {
settings: { settings: {
SCROLL_INTO_ENABLED: SCROLL_INTO_ENABLED:
typeof this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED !== typeof this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED !== "undefined"
"undefined"
? this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED ? this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED
: true, : true,
@@ -394,24 +393,6 @@ export default {
this.settings[key] = value this.settings[key] = value
this.$store.commit("postwoman/applySetting", [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() { signInWithGoogle() {
const provider = new firebase.auth.GoogleAuthProvider() const provider = new firebase.auth.GoogleAuthProvider()
firebase firebase
@@ -437,9 +418,74 @@ export default {
} }
}) })
.catch(err => { .catch(err => {
this.$toast.show(err.message || err, { // An error happened.
icon: "error", 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() { 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 => { .catch(err => {
this.$toast.show(err.message || err, { this.$toast.show(err.message || err, {
icon: "error", icon: "error",
}) })
}) })
this.$toast.info(this.$t("logged_out"), {
icon: "vpn_key",
})
}, },
toggleSettings(s, v) { toggleSettings(s, v) {
fb.writeSettings(s, !v) fb.writeSettings(s, !v)