feat: typescript support in auth components
Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
@@ -116,17 +116,16 @@
|
|||||||
</SmartModal>
|
</SmartModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { defineComponent } from "@nuxtjs/composition-api"
|
import { defineComponent } from "@nuxtjs/composition-api"
|
||||||
import { applySetting } from "~/newstore/settings"
|
|
||||||
import {
|
import {
|
||||||
signInUserWithGoogle,
|
signInUserWithGoogle,
|
||||||
getSignInMethodsForEmail,
|
|
||||||
signInWithEmailAndPassword,
|
|
||||||
signInUserWithGithub,
|
signInUserWithGithub,
|
||||||
setProviderInfo,
|
setProviderInfo,
|
||||||
currentUser$,
|
currentUser$,
|
||||||
signInWithEmail,
|
signInWithEmail,
|
||||||
|
linkWithFBCredential,
|
||||||
|
getGithubCredentialFromResult,
|
||||||
} from "~/helpers/fb/auth"
|
} from "~/helpers/fb/auth"
|
||||||
import { setLocalConfig } from "~/newstore/localpersistence"
|
import { setLocalConfig } from "~/newstore/localpersistence"
|
||||||
import { useStreamSubscriber } from "~/helpers/utils/composables"
|
import { useStreamSubscriber } from "~/helpers/utils/composables"
|
||||||
@@ -162,7 +161,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showLoginSuccess() {
|
showLoginSuccess() {
|
||||||
this.$toast.success(this.$t("auth.login_success"), {
|
this.$toast.success(this.$t("auth.login_success").toString(), {
|
||||||
icon: "vpn_key",
|
icon: "vpn_key",
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -170,28 +169,7 @@ export default defineComponent({
|
|||||||
this.signingInWithGoogle = true
|
this.signingInWithGoogle = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { additionalUserInfo } = await signInUserWithGoogle()
|
await signInUserWithGoogle()
|
||||||
|
|
||||||
if (additionalUserInfo.isNewUser) {
|
|
||||||
this.$toast.info(
|
|
||||||
`${this.$t("action.turn_on")} ${this.$t("auth.sync")}`,
|
|
||||||
{
|
|
||||||
icon: "sync",
|
|
||||||
duration: null,
|
|
||||||
closeOnSwipe: false,
|
|
||||||
action: {
|
|
||||||
text: this.$t("action.yes"),
|
|
||||||
onClick: (_, toastObject) => {
|
|
||||||
applySetting("syncHistory", true)
|
|
||||||
applySetting("syncCollections", true)
|
|
||||||
applySetting("syncEnvironments", true)
|
|
||||||
toastObject.remove()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showLoginSuccess()
|
this.showLoginSuccess()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
@@ -201,44 +179,24 @@ export default defineComponent({
|
|||||||
// User's email already exists.
|
// User's email already exists.
|
||||||
// The pending Google credential.
|
// The pending Google credential.
|
||||||
const pendingCred = e.credential
|
const pendingCred = e.credential
|
||||||
// The provider account's email address.
|
|
||||||
const email = e.email
|
|
||||||
// Get sign-in methods for this email.
|
|
||||||
const methods = await getSignInMethodsForEmail(email)
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
const password = promptUserForPassword() // TODO: implement promptUserForPassword.
|
|
||||||
|
|
||||||
const user = await signInWithEmailAndPassword(email, password)
|
|
||||||
await user.linkWithCredential(pendingCred)
|
|
||||||
|
|
||||||
this.showLoginSuccess()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$toast.info(`${this.$t("auth.account_exists")}`, {
|
this.$toast.info(`${this.$t("auth.account_exists")}`, {
|
||||||
icon: "vpn_key",
|
icon: "vpn_key",
|
||||||
duration: null,
|
duration: 0,
|
||||||
closeOnSwipe: false,
|
closeOnSwipe: false,
|
||||||
action: {
|
action: {
|
||||||
text: this.$t("action.yes"),
|
text: this.$t("action.yes").toString(),
|
||||||
onClick: async (_, toastObject) => {
|
onClick: async (_, toastObject) => {
|
||||||
const { user } = await signInWithGithub()
|
const { user } = await signInUserWithGithub()
|
||||||
await user.linkWithCredential(pendingCred)
|
await linkWithFBCredential(user, pendingCred)
|
||||||
|
|
||||||
this.showLoginSuccess()
|
this.showLoginSuccess()
|
||||||
|
|
||||||
toastObject.remove()
|
toastObject.goAway(0)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
this.$toast.error(this.$t("error.something_went_wrong").toString(), {
|
||||||
icon: "error_outline",
|
icon: "error_outline",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -250,29 +208,11 @@ export default defineComponent({
|
|||||||
this.signingInWithGitHub = true
|
this.signingInWithGitHub = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { credential, additionalUserInfo } = await signInUserWithGithub()
|
const result = await signInUserWithGithub()
|
||||||
|
const credential = getGithubCredentialFromResult(result)!
|
||||||
|
const token = credential.accessToken
|
||||||
|
|
||||||
setProviderInfo(credential.providerId, credential.accessToken)
|
setProviderInfo(result.providerId!, token!)
|
||||||
|
|
||||||
if (additionalUserInfo.isNewUser) {
|
|
||||||
this.$toast.info(
|
|
||||||
`${this.$t("action.turn_on")} ${this.$t("auth.sync")}`,
|
|
||||||
{
|
|
||||||
icon: "sync",
|
|
||||||
duration: null,
|
|
||||||
closeOnSwipe: false,
|
|
||||||
action: {
|
|
||||||
text: this.$t("action.yes"),
|
|
||||||
onClick: (_, toastObject) => {
|
|
||||||
applySetting("syncHistory", true)
|
|
||||||
applySetting("syncCollections", true)
|
|
||||||
applySetting("syncEnvironments", true)
|
|
||||||
toastObject.remove()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showLoginSuccess()
|
this.showLoginSuccess()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -283,44 +223,24 @@ export default defineComponent({
|
|||||||
// User's email already exists.
|
// User's email already exists.
|
||||||
// The pending Google credential.
|
// The pending Google credential.
|
||||||
const pendingCred = e.credential
|
const pendingCred = e.credential
|
||||||
// The provider account's email address.
|
|
||||||
const email = e.email
|
|
||||||
// Get sign-in methods for this email.
|
|
||||||
const methods = await getSignInMethodsForEmail(email)
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
const password = promptUserForPassword() // TODO: implement promptUserForPassword.
|
|
||||||
|
|
||||||
const user = await signInWithEmailAndPassword(email, password)
|
|
||||||
await user.linkWithCredential(pendingCred)
|
|
||||||
|
|
||||||
this.showLoginSuccess()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$toast.info(`${this.$t("auth.account_exists")}`, {
|
this.$toast.info(`${this.$t("auth.account_exists")}`, {
|
||||||
icon: "vpn_key",
|
icon: "vpn_key",
|
||||||
duration: null,
|
duration: 0,
|
||||||
closeOnSwipe: false,
|
closeOnSwipe: false,
|
||||||
action: {
|
action: {
|
||||||
text: this.$t("action.yes"),
|
text: this.$t("action.yes").toString(),
|
||||||
onClick: async (_, toastObject) => {
|
onClick: async (_, toastObject) => {
|
||||||
const { user } = await signInUserWithGoogle()
|
const { user } = await signInUserWithGoogle()
|
||||||
await user.linkWithCredential(pendingCred)
|
await linkWithFBCredential(user, pendingCred)
|
||||||
|
|
||||||
this.showLoginSuccess()
|
this.showLoginSuccess()
|
||||||
|
|
||||||
toastObject.remove()
|
toastObject.goAway(0)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
this.$toast.error(this.$t("error.something_went_wrong").toString(), {
|
||||||
icon: "error_outline",
|
icon: "error_outline",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import {
|
|||||||
signInWithEmailLink as signInWithEmailLinkFB,
|
signInWithEmailLink as signInWithEmailLinkFB,
|
||||||
ActionCodeSettings,
|
ActionCodeSettings,
|
||||||
signOut,
|
signOut,
|
||||||
|
linkWithCredential,
|
||||||
|
AuthCredential,
|
||||||
|
UserCredential,
|
||||||
} from "firebase/auth"
|
} from "firebase/auth"
|
||||||
import {
|
import {
|
||||||
onSnapshot,
|
onSnapshot,
|
||||||
@@ -176,6 +179,13 @@ export async function getSignInMethodsForEmail(email: string) {
|
|||||||
return await fetchSignInMethodsForEmail(getAuth(), email)
|
return await fetchSignInMethodsForEmail(getAuth(), email)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function linkWithFBCredential(
|
||||||
|
user: User,
|
||||||
|
credential: AuthCredential
|
||||||
|
) {
|
||||||
|
return await linkWithCredential(user, credential)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an email with the signin link to the user
|
* Sends an email with the signin link to the user
|
||||||
*
|
*
|
||||||
@@ -244,6 +254,10 @@ export async function setProviderInfo(id: string, token: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getGithubCredentialFromResult(result: UserCredential) {
|
||||||
|
return GithubAuthProvider.credentialFromResult(result)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Vue composable function that is called when the auth status
|
* A Vue composable function that is called when the auth status
|
||||||
* is being updated to being logged in (fired multiple times),
|
* is being updated to being logged in (fired multiple times),
|
||||||
|
|||||||
Reference in New Issue
Block a user