feat: load allowed login methods from .env (#3264)

Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
Akash K
2023-08-18 21:23:56 +05:30
committed by GitHub
parent c626fb9241
commit ce7adf6da3

View File

@@ -9,27 +9,12 @@
<template #body> <template #body>
<div v-if="mode === 'sign-in'" class="flex flex-col space-y-2"> <div v-if="mode === 'sign-in'" class="flex flex-col space-y-2">
<HoppSmartItem <HoppSmartItem
:loading="signingInWithGitHub" v-for="provider in allowedAuthProviders"
:icon="IconGithub" :key="provider.id"
:label="`${t('auth.continue_with_github')}`" :loading="provider.isLoading.value"
@click="signInWithGithub" :icon="provider.icon"
/> :label="provider.label"
<HoppSmartItem @click="provider.action"
:loading="signingInWithGoogle"
:icon="IconGoogle"
:label="`${t('auth.continue_with_google')}`"
@click="signInWithGoogle"
/>
<HoppSmartItem
:loading="signingInWithMicrosoft"
:icon="IconMicrosoft"
:label="`${t('auth.continue_with_microsoft')}`"
@click="signInWithMicrosoft"
/>
<HoppSmartItem
:icon="IconEmail"
:label="`${t('auth.continue_with_email')}`"
@click="mode = 'email'"
/> />
<hr v-if="additonalLoginItems.length > 0" /> <hr v-if="additonalLoginItems.length > 0" />
@@ -123,132 +108,138 @@
</HoppSmartModal> </HoppSmartModal>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { defineComponent, computed } from "vue" import { Ref, computed, onMounted, ref } from "vue"
import { useStreamSubscriber } from "@composables/stream"
import { useToast } from "@composables/toast"
import { useI18n } from "@composables/i18n"
import { platform } from "~/platform" import { platform } from "~/platform"
import { setLocalConfig } from "~/newstore/localpersistence"
import IconGithub from "~icons/auth/github" import IconGithub from "~icons/auth/github"
import IconGoogle from "~icons/auth/google" import IconGoogle from "~icons/auth/google"
import IconEmail from "~icons/auth/email" import IconEmail from "~icons/auth/email"
import IconMicrosoft from "~icons/auth/microsoft" import IconMicrosoft from "~icons/auth/microsoft"
import IconArrowLeft from "~icons/lucide/arrow-left" import IconArrowLeft from "~icons/lucide/arrow-left"
import { setLocalConfig } from "~/newstore/localpersistence"
import { useStreamSubscriber } from "@composables/stream"
import { useToast } from "@composables/toast"
import { useI18n } from "@composables/i18n"
import { LoginItemDef } from "~/platform/auth" import { LoginItemDef } from "~/platform/auth"
export default defineComponent({ defineProps<{
props: { show: boolean
show: Boolean, }>()
},
emits: ["hide-modal"],
setup() {
const { subscribeToStream } = useStreamSubscriber()
const tosLink = import.meta.env.VITE_APP_TOS_LINK const emit = defineEmits<{
const privacyPolicyLink = import.meta.env.VITE_APP_PRIVACY_POLICY_LINK (e: "hide-modal"): void
}>()
return { const { subscribeToStream } = useStreamSubscriber()
subscribeToStream, const t = useI18n()
t: useI18n(), const toast = useToast()
additonalLoginItems: computed(
() => platform.auth.additionalLoginItems ?? []
),
toast: useToast(),
IconGithub,
IconGoogle,
IconEmail,
IconMicrosoft,
IconArrowLeft,
tosLink,
privacyPolicyLink,
}
},
data() {
return {
form: {
email: "",
},
signingInWithGoogle: false,
signingInWithGitHub: false,
signingInWithMicrosoft: false,
signingInWithEmail: false,
mode: "sign-in",
}
},
mounted() {
const currentUser$ = platform.auth.getCurrentUserStream()
this.subscribeToStream(currentUser$, (user) => { const form = {
if (user) this.hideModal() email: "",
}) }
},
methods: {
async doAdditionalLoginItemClickAction(item: LoginItemDef) {
await item.onClick()
this.$emit("hide-modal")
},
showLoginSuccess() {
this.toast.success(`${this.t("auth.login_success")}`)
},
async signInWithGoogle() {
this.signingInWithGoogle = true
try { const signingInWithGoogle = ref(false)
await platform.auth.signInUserWithGoogle() const signingInWithGitHub = ref(false)
} catch (e) { const signingInWithMicrosoft = ref(false)
console.error(e) const signingInWithEmail = ref(false)
/* const mode = ref("sign-in")
const tosLink = import.meta.env.VITE_APP_TOS_LINK
const privacyPolicyLink = import.meta.env.VITE_APP_PRIVACY_POLICY_LINK
type AuthProviderItem = {
id: string
icon: typeof IconGithub
label: string
action: (...args: any[]) => any
isLoading: Ref<boolean>
}
const additonalLoginItems = computed(
() => platform.auth.additionalLoginItems ?? []
)
const doAdditionalLoginItemClickAction = async (item: LoginItemDef) => {
await item.onClick()
emit("hide-modal")
}
onMounted(() => {
const currentUser$ = platform.auth.getCurrentUserStream()
subscribeToStream(currentUser$, (user) => {
if (user) hideModal()
})
})
const showLoginSuccess = () => {
toast.success(`${t("auth.login_success")}`)
}
const signInWithGoogle = async () => {
signingInWithGoogle.value = true
try {
await platform.auth.signInUserWithGoogle()
} catch (e) {
console.error(e)
/*
A auth/account-exists-with-different-credential Firebase error wont happen between Google and any other providers A auth/account-exists-with-different-credential Firebase error wont happen between Google and any other providers
Seems Google account overwrites accounts of other providers https://github.com/firebase/firebase-android-sdk/issues/25 Seems Google account overwrites accounts of other providers https://github.com/firebase/firebase-android-sdk/issues/25
*/ */
this.toast.error(`${this.t("error.something_went_wrong")}`) toast.error(`${t("error.something_went_wrong")}`)
} }
this.signingInWithGoogle = false signingInWithGoogle.value = false
}, }
async signInWithGithub() {
this.signingInWithGitHub = true
const result = await platform.auth.signInUserWithGithub() const signInWithGithub = async () => {
signingInWithGitHub.value = true
if (!result) { const result = await platform.auth.signInUserWithGithub()
this.signingInWithGitHub = false
return
}
if (result.type === "success") { if (!result) {
// this.showLoginSuccess() signingInWithGitHub.value = false
} else if (result.type === "account-exists-with-different-cred") { return
this.toast.info(`${this.t("auth.account_exists")}`, { }
duration: 0,
closeOnSwipe: false,
action: {
text: `${this.t("action.yes")}`,
onClick: async (_, toastObject) => {
await result.link()
this.showLoginSuccess()
toastObject.goAway(0) if (result.type === "success") {
}, // this.showLoginSuccess()
}, } else if (result.type === "account-exists-with-different-cred") {
}) toast.info(`${t("auth.account_exists")}`, {
} else { duration: 0,
console.log("error logging into github", result.err) closeOnSwipe: false,
this.toast.error(`${this.t("error.something_went_wrong")}`) action: {
} text: `${t("action.yes")}`,
onClick: async (_, toastObject) => {
await result.link()
showLoginSuccess()
this.signingInWithGitHub = false toastObject.goAway(0)
}, },
async signInWithMicrosoft() { },
this.signingInWithMicrosoft = true })
} else {
console.log("error logging into github", result.err)
toast.error(`${t("error.something_went_wrong")}`)
}
try { signingInWithGitHub.value = false
await platform.auth.signInUserWithMicrosoft() }
// this.showLoginSuccess()
} catch (e) { const signInWithMicrosoft = async () => {
console.error(e) signingInWithMicrosoft.value = true
/*
try {
await platform.auth.signInUserWithMicrosoft()
// this.showLoginSuccess()
} catch (e) {
console.error(e)
/*
A auth/account-exists-with-different-credential Firebase error wont happen between MS with Google or Github A auth/account-exists-with-different-credential Firebase error wont happen between MS with Google or Github
If a Github account exists and user then logs in with MS email we get a "Something went wrong toast" and console errors and MS replaces GH as only provider. If a Github account exists and user then logs in with MS email we get a "Something went wrong toast" and console errors and MS replaces GH as only provider.
The error messages are as follows: The error messages are as follows:
@@ -256,34 +247,82 @@ export default defineComponent({
@firebase/auth: Auth (9.6.11): INTERNAL ASSERTION FAILED: Pending promise was never set @firebase/auth: Auth (9.6.11): INTERNAL ASSERTION FAILED: Pending promise was never set
They may be related to https://github.com/firebase/firebaseui-web/issues/947 They may be related to https://github.com/firebase/firebaseui-web/issues/947
*/ */
this.toast.error(`${this.t("error.something_went_wrong")}`) toast.error(`${t("error.something_went_wrong")}`)
} }
this.signingInWithMicrosoft = false signingInWithMicrosoft.value = false
}, }
async signInWithEmail() {
this.signingInWithEmail = true
await platform.auth const signInWithEmail = async () => {
.signInWithEmail(this.form.email) signingInWithEmail.value = true
.then(() => {
this.mode = "email-sent" await platform.auth
setLocalConfig("emailForSignIn", this.form.email) .signInWithEmail(form.email)
}) .then(() => {
.catch((e) => { mode.value = "email-sent"
console.error(e) setLocalConfig("emailForSignIn", form.email)
this.toast.error(e.message) })
this.signingInWithEmail = false .catch((e) => {
}) console.error(e)
.finally(() => { toast.error(e.message)
this.signingInWithEmail = false signingInWithEmail.value = false
}) })
}, .finally(() => {
hideModal() { signingInWithEmail.value = false
this.mode = "sign-in" })
this.toast.clear() }
this.$emit("hide-modal")
}, const hideModal = () => {
mode.value = "sign-in"
toast.clear()
emit("hide-modal")
}
const authProviders: AuthProviderItem[] = [
{
id: "GITHUB",
icon: IconGithub,
label: t("auth.continue_with_github"),
action: signInWithGithub,
isLoading: signingInWithGitHub,
}, },
}) {
id: "GOOGLE",
icon: IconGoogle,
label: t("auth.continue_with_google"),
action: signInWithGoogle,
isLoading: signingInWithGoogle,
},
{
id: "MICROSOFT",
icon: IconMicrosoft,
label: t("auth.continue_with_microsoft"),
action: signInWithMicrosoft,
isLoading: signingInWithMicrosoft,
},
{
id: "EMAIL",
icon: IconEmail,
label: t("auth.continue_with_email"),
action: () => {
mode.value = "email"
},
isLoading: signingInWithEmail,
},
]
const allowedAuthProvidersIDsString: string | undefined = import.meta.env
.VITE_ALLOWED_AUTH_PROVIDERS
const allowedAuthProvidersIDs = allowedAuthProvidersIDsString
? allowedAuthProvidersIDsString.split(",")
: []
const allowedAuthProviders =
allowedAuthProvidersIDs.length > 0
? authProviders.filter((provider) =>
allowedAuthProvidersIDs.includes(provider.id)
)
: authProviders
</script> </script>