From e1c34a3689da74db0bfcf0526240d1b1b32fdd6a Mon Sep 17 00:00:00 2001 From: Dmitry Yankowski Date: Thu, 27 Feb 2020 18:20:21 -0500 Subject: [PATCH 01/10] Add --staged parameter to pretty-quick Makes it so you don't have to re-stage manually after pre-commit hook is run --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8e7e2baec..b4e3ebe9c 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "e2e": "cypress run", "e2e:open": "cypress open", "dev:e2e": "server-test dev :3000 e2e:open", - "pretty-quick": "pretty-quick --pattern \"**/*.*(html|js|json|vue)\"", + "pretty-quick": "pretty-quick --staged --pattern \"**/*.*(html|js|json|vue)\"", "test": "start-server-and-test start http-get://localhost:3000 e2e" }, "husky": { From 3bbe71f2c967dc13c1f99f973c877f43f7366cce Mon Sep 17 00:00:00 2001 From: Liyas Thomas Date: Fri, 28 Feb 2020 05:35:28 +0530 Subject: [PATCH 02/10] :alembic: Link multiple auth providers --- components/firebase/login.vue | 148 ++++++++++++++++++++++++++-- pages/settings.vue | 175 +++++++++++++++++++++++++++++----- 2 files changed, 292 insertions(+), 31 deletions(-) diff --git a/components/firebase/login.vue b/components/firebase/login.vue index 06594cb4a..31120ba98 100644 --- a/components/firebase/login.vue +++ b/components/firebase/login.vue @@ -66,8 +66,9 @@ export default { action: { text: this.$t("yes"), onClick: (e, toastObject) => { - fb.writeSettings("syncHistory", false) + fb.writeSettings("syncHistory", true) fb.writeSettings("syncCollections", true) + fb.writeSettings("syncEnvironments", true) this.$router.push({ path: "/settings" }) toastObject.remove() }, @@ -76,9 +77,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() { @@ -95,8 +161,9 @@ export default { action: { text: this.$t("yes"), onClick: (e, toastObject) => { - fb.writeSettings("syncHistory", false) + fb.writeSettings("syncHistory", true) fb.writeSettings("syncCollections", true) + fb.writeSettings("syncEnvironments", true) this.$router.push({ path: "/settings" }) toastObject.remove() }, @@ -105,9 +172,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.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() + }, + }, + }) + }) + } }) }, }, diff --git a/pages/settings.vue b/pages/settings.vue index 98ec14d17..e032e65fe 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -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) From 3a2bb63c981c8b9fa37de6c40dcc1c9416f217b4 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2020 00:29:02 +0000 Subject: [PATCH 03/10] docs: update README.md [skip ci] --- README.md | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 111eff342..7eefa95b7 100644 --- a/README.md +++ b/README.md @@ -325,29 +325,34 @@ See the [CHANGELOG](CHANGELOG.md) file for details. * ([contributors](https://github.com/liyasthomas/postwoman/graphs/contributors)) ### Collaborators +[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-) - + + - - - - - - - + + + + + + + - - - - - + + + + + +
Liyas Thomas
Liyas Thomas

💻 🎨
John Harker
John Harker

💻 🎨
Nicholas La Roux
Nicholas La Roux

💻
Thomas Yuba
Thomas Yuba

💻
Nick Palenchar
Nick Palenchar

💻
Andrew Bastin
Andrew Bastin

💻
Vladislav
Vladislav

💻

Liyas Thomas

💻 🎨

John Harker

💻 🎨

Nicholas La Roux

💻

Thomas Yuba

💻

Nick Palenchar

💻

Andrew Bastin

💻

Vladislav

💻
izerozlu
izerozlu

💻
Jacob Anavisca
Jacob Anavisca

💻
Nityananda Gohain
Nityananda Gohain

💻
Hossein Nedaee
Hossein Nedaee

💻
James George
James George

💻

izerozlu

💻

Jacob Anavisca

💻

Nityananda Gohain

💻

Hossein Nedaee

💻

James George

💻

Dmitry Yankowski

💻
+ + See the list of [contributors](https://github.com/liyasthomas/postwoman/graphs/contributors) who participated in this project. From ab7ee92112c3eb313678147765c2b8fa5a4a3f27 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2020 00:29:03 +0000 Subject: [PATCH 04/10] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index ca0269c27..0c4cde53e 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -114,11 +114,21 @@ "contributions": [ "code" ] + }, + { + "login": "dmitryyankowski", + "name": "Dmitry Yankowski", + "avatar_url": "https://avatars0.githubusercontent.com/u/20114263?v=4", + "profile": "https://dmitryyankowski.com", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, "projectName": "postwoman", "projectOwner": "liyasthomas", "repoType": "github", - "repoHost": "https://github.com" + "repoHost": "https://github.com", + "skipCi": true } From 154c2b2da3811f51a3c51c049c70175c87f27cc8 Mon Sep 17 00:00:00 2001 From: Dmitry Yankowski Date: Thu, 27 Feb 2020 21:50:00 -0500 Subject: [PATCH 05/10] Fix scoping and toast notifications for auth/settings page --- components/firebase/login.vue | 250 ++++++++++++++++++--------------- lang/en-US.js | 1 + pages/settings.vue | 257 +++++++++++++++++++--------------- 3 files changed, 279 insertions(+), 229 deletions(-) diff --git a/components/firebase/login.vue b/components/firebase/login.vue index 31120ba98..1734db5f3 100644 --- a/components/firebase/login.vue +++ b/components/firebase/login.vue @@ -50,31 +50,37 @@ export default { fb, } }, - methods: { + showLoginSuccess() { + this.$toast.info(this.$t("login_success"), { + icon: "vpn_key", + }) + }, signInWithGoogle() { const provider = new firebase.auth.GoogleAuthProvider() + const self = this firebase .auth() .signInWithPopup(provider) .then(({ additionalUserInfo }) => { if (additionalUserInfo.isNewUser) { - this.$toast.info(`${this.$t("turn_on")} ${this.$t("sync")}`, { + self.$toast.info(`${self.$t("turn_on")} ${self.$t("sync")}`, { icon: "sync", duration: null, closeOnSwipe: false, action: { - text: this.$t("yes"), + text: self.$t("yes"), onClick: (e, toastObject) => { fb.writeSettings("syncHistory", true) fb.writeSettings("syncCollections", true) fb.writeSettings("syncEnvironments", true) - this.$router.push({ path: "/settings" }) + self.$router.push({ path: "/settings" }) toastObject.remove() }, }, }) } + self.showLoginSuccess() }) .catch(err => { // An error happened. @@ -86,90 +92,98 @@ export default { // 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() - }) + firebase + .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. + self.showLoginSuccess() + }) + return + } - toastObject.remove() + self.$toast.info(`${self.$t("login_with")}`, { + icon: "vpn_key", + duration: null, + closeOnSwipe: false, + action: { + text: self.$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. + firebase + .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. + self.showLoginSuccess() + }) + }) + + toastObject.remove() + }, }, - }, + }) }) - }) } }) }, signInWithGithub() { const provider = new firebase.auth.GithubAuthProvider() + const self = this firebase .auth() .signInWithPopup(provider) .then(({ additionalUserInfo }) => { if (additionalUserInfo.isNewUser) { - this.$toast.info(`${this.$t("turn_on")} ${this.$t("sync")}`, { + self.$toast.info(`${self.$t("turn_on")} ${self.$t("sync")}`, { icon: "sync", duration: null, closeOnSwipe: false, action: { - text: this.$t("yes"), + text: self.$t("yes"), onClick: (e, toastObject) => { fb.writeSettings("syncHistory", true) fb.writeSettings("syncCollections", true) fb.writeSettings("syncEnvironments", true) - this.$router.push({ path: "/settings" }) + self.$router.push({ path: "/settings" }) toastObject.remove() }, }, }) } + self.showLoginSuccess() }) .catch(err => { // An error happened. @@ -181,64 +195,70 @@ export default { // 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() - }) + firebase + .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. + firebase + .auth() + .signInWithEmailAndPassword(email, password) + .then(function(user) { + // Step 4a. + return user.linkWithCredential(pendingCred) }) + .then(function() { + // Google account successfully linked to the existing Firebase user. + self.showLoginSuccess() + }) + return + } - toastObject.remove() + self.$toast.info(`${self.$t("login_with")}`, { + icon: "vpn_key", + duration: null, + closeOnSwipe: false, + action: { + text: self.$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. + firebase + .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) { + self.showLoginSuccess() + }) + }) + + toastObject.remove() + }, }, - }, + }) }) - }) } }) }, diff --git a/lang/en-US.js b/lang/en-US.js index e7c5e755c..344075d7a 100644 --- a/lang/en-US.js +++ b/lang/en-US.js @@ -258,6 +258,7 @@ export default { installed: "Installed", login_with: "Login with", logged_out: "Logged out", + login_success: "Successfully logged in", logout: "Logout", account: "Account", scrollInto_use_toggle: "Auto scroll", diff --git a/pages/settings.vue b/pages/settings.vue index e032e65fe..43ff8f696 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -382,6 +382,11 @@ export default { this.applySetting("THEME_COLOR", color.toUpperCase()) this.applySetting("THEME_COLOR_VIBRANT", vibrant) }, + showLoginSuccess() { + this.$toast.info(this.$t("login_success"), { + icon: "vpn_key", + }) + }, getActiveColor() { // This strips extra spaces and # signs from the strings. const strip = str => str.replace(/#/g, "").replace(/ /g, "") @@ -395,12 +400,13 @@ export default { }, signInWithGoogle() { const provider = new firebase.auth.GoogleAuthProvider() + const self = this firebase .auth() .signInWithPopup(provider) .then(({ additionalUserInfo }) => { if (additionalUserInfo.isNewUser) { - this.$toast.info(`${this.$t("turn_on")} ${this.$t("sync")}`, { + self.$toast.info(`${this.$t("turn_on")} ${this.$t("sync")}`, { icon: "sync", duration: null, closeOnSwipe: false, @@ -416,6 +422,7 @@ export default { }, }) } + self.showLoginSuccess() }) .catch(err => { // An error happened. @@ -427,90 +434,103 @@ export default { // 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() - }) + firebase + .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. + firebase + .auth() + .signInWithEmailAndPassword(email, password) + .then(function(user) { + // Step 4a. + return user.linkWithCredential(pendingCred) }) + .then(function() { + // Google account successfully linked to the existing Firebase user. + self.showLoginSuccess() + }) + return + } - toastObject.remove() + self.$toast.info(`${self.$t("login_with")}`, { + icon: "vpn_key", + duration: null, + closeOnSwipe: false, + action: { + text: self.$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. + firebase + .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. + self.$toast.info(self.$t("login_success"), { + icon: "vpn_key", + }) + }) + }) + + toastObject.remove() + }, }, - }, + }) }) - }) } }) }, signInWithGithub() { const provider = new firebase.auth.GithubAuthProvider() + const self = this firebase .auth() .signInWithPopup(provider) .then(({ additionalUserInfo }) => { if (additionalUserInfo.isNewUser) { - this.$toast.info(`${this.$t("turn_on")} ${this.$t("sync")}`, { + self.$toast.info(`${self.$t("turn_on")} ${self.$t("sync")}`, { icon: "sync", duration: null, closeOnSwipe: false, action: { - text: this.$t("yes"), + text: self.$t("yes"), onClick: (e, toastObject) => { fb.writeSettings("syncHistory", true) fb.writeSettings("syncCollections", true) fb.writeSettings("syncEnvironments", true) - this.$router.push({ path: "/settings" }) + self.$router.push({ path: "/settings" }) toastObject.remove() }, }, }) } + self.$toast.info(self.$t("login_success"), { + icon: "vpn_key", + }) }) .catch(err => { // An error happened. @@ -522,64 +542,72 @@ export default { // 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() - }) + firebase + .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. + self.$toast.info(self.$t("login_success"), { + icon: "vpn_key", + }) + }) + return + } - toastObject.remove() + self.$toast.info(`${this.$t("login_with")}`, { + icon: "vpn_key", + duration: null, + closeOnSwipe: false, + action: { + text: self.$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. + firebase + .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. + self.showLoginSuccess() + }) + }) + + toastObject.remove() + }, }, - }, + }) }) - }) } }) }, @@ -589,15 +617,16 @@ export default { }, logout() { fb.currentUser = null + const self = this firebase .auth() .signOut() .catch(err => { - this.$toast.show(err.message || err, { + self.$toast.show(err.message || err, { icon: "error", }) }) - this.$toast.info(this.$t("logged_out"), { + self.$toast.info(this.$t("logged_out"), { icon: "vpn_key", }) }, From 5daf4a19b7939276ad9ebafd4e018dc9a4288ed7 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Thu, 27 Feb 2020 21:32:08 -0500 Subject: [PATCH 06/10] Added Ctrl+Enter as a short cut to run GraphQL Query --- components/graphql/queryeditor.vue | 57 ++++++++++++++++++------------ 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/components/graphql/queryeditor.vue b/components/graphql/queryeditor.vue index c76ba02d7..6378f5f09 100644 --- a/components/graphql/queryeditor.vue +++ b/components/graphql/queryeditor.vue @@ -5,17 +5,17 @@ From 2f2580d2d39871db66988a53b66668b874343bb7 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Thu, 27 Feb 2020 21:33:43 -0500 Subject: [PATCH 07/10] Hooked up onRunGQLQuery editor command --- pages/graphql.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/pages/graphql.vue b/pages/graphql.vue index e2b5f7c37..ca8641da5 100644 --- a/pages/graphql.vue +++ b/pages/graphql.vue @@ -169,6 +169,7 @@ Date: Thu, 27 Feb 2020 21:44:52 -0500 Subject: [PATCH 09/10] Refactor default.vue to use getPlatformSpecialKey --- layouts/default.vue | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/layouts/default.vue b/layouts/default.vue index 6b18381da..a77c8871b 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -642,6 +642,7 @@ import intializePwa from "../assets/js/pwa" import * as version from "../.postwoman/version.json" import { hasExtensionInstalled } from "../functions/strategies/ExtensionStrategy" import { hasChromeExtensionInstalled } from "../functions/strategies/ChromeStrategy" +import { getPlatformSpecialKey } from "~/functions/platformutils" import firebase from "firebase/app" import { fb } from "../functions/fb" @@ -653,9 +654,7 @@ export default { }, methods: { - getSpecialKey() { - return /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ? "⌘" : "Ctrl" - }, + getSpecialKey: getPlatformSpecialKey, linkActive(path) { return { "nuxt-link-exact-active": this.$route.path === path, From e5e66d8cc00d62af26b30d7d9169349e3edd92ea Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Thu, 27 Feb 2020 21:50:01 -0500 Subject: [PATCH 10/10] Added shortcut key to the Run Query button tooltip --- pages/graphql.vue | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pages/graphql.vue b/pages/graphql.vue index ca8641da5..4d07a1022 100644 --- a/pages/graphql.vue +++ b/pages/graphql.vue @@ -153,7 +153,10 @@
-