Created
October 23, 2022 16:22
-
-
Save Shahinyanm/5131ac07549e80fb43ba202f668841b8 to your computer and use it in GitHub Desktop.
Auth Login Page
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <template> | |
| <auth-container v-if="!auth.profile"> | |
| <router-view /> | |
| </auth-container> | |
| </template> | |
| <script lang="ts" setup> | |
| import { useAuthStore } from "@/lib/store/auth"; | |
| import { computed, onBeforeMount, provide, ref } from "vue"; | |
| import { useRouter } from "vue-router"; | |
| import AuthContainer from "../../components/AuthContainer.vue"; | |
| const auth = useAuthStore(); | |
| const router = useRouter(); | |
| const email = ref(""); | |
| const password = ref(""); | |
| const remember = ref(false); | |
| const entered = computed(() => !!email.value && !!password.value); | |
| provide("email", email); | |
| provide("password", password); | |
| provide("remember", remember); | |
| provide("entered", entered); | |
| onBeforeMount(async () => { | |
| if (auth.profile) { | |
| await router.replace({ name: "dashboard" }); | |
| } | |
| }); | |
| </script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <template> | |
| <auth-title> | |
| {{ $t("auth.loginToYourAccount") }} | |
| </auth-title> | |
| <auth-social-list> | |
| <auth-google-button | |
| :processing="processingGoogle" | |
| :disabled="processingPassword" | |
| @success="googleLogin" | |
| > | |
| {{ $t("auth.logInWithGoogle") }} | |
| </auth-google-button> | |
| <auth-facebook-button | |
| :processing="processingFacebook" | |
| :disabled="processingPassword" | |
| @success="facebookLogin" | |
| > | |
| {{ $t("auth.logInWithFacebook") }} | |
| </auth-facebook-button> | |
| </auth-social-list> | |
| <auth-password-option /> | |
| <auth-sign-in-password-form | |
| v-model:email="email" | |
| v-model:password="password" | |
| v-model:remember="remember" | |
| :processing="processingPassword" | |
| @submit="passwordLogin" | |
| /> | |
| </template> | |
| <script lang="ts" setup> | |
| import { | |
| issueFacebookGrantAccessToken, | |
| issueGoogleGrantAccessToken, | |
| issuePasswordGrantAccessToken, | |
| } from "@/lib/api/oauth"; | |
| import { | |
| InvalidCredentialsError, | |
| InvalidOtpError, | |
| } from "@/lib/api/oauth/errors"; | |
| import { useAuthStore } from "@/lib/store/auth"; | |
| import { useToast } from "@/lib/ui/hooks/toast"; | |
| import { get } from "lodash"; | |
| import { inject, ref, type Ref } from "vue"; | |
| import { useRouter } from "vue-router"; | |
| import AuthFacebookButton from "../../components/AuthFacebookButton.vue"; | |
| import AuthGoogleButton from "../../components/AuthGoogleButton.vue"; | |
| import AuthPasswordOption from "../../components/AuthPasswordOption.vue"; | |
| import AuthSignInPasswordForm from "../../components/AuthSignInPasswordForm.vue"; | |
| import AuthSocialList from "../../components/AuthSocialList.vue"; | |
| import AuthTitle from "../../components/AuthTitle.vue"; | |
| const auth = useAuthStore(); | |
| const router = useRouter(); | |
| const toast = useToast(); | |
| const processingGoogle = ref(false); | |
| const processingFacebook = ref(false); | |
| const processingPassword = ref(false); | |
| const email = inject("email") as Ref<string>; | |
| const password = inject("password") as Ref<string>; | |
| const remember = inject("remember") as Ref<boolean>; | |
| async function googleLogin(token: string): Promise<void> { | |
| processingGoogle.value = true; | |
| try { | |
| const accessToken = await issueGoogleGrantAccessToken({ | |
| token, | |
| }); | |
| await auth.authorize(accessToken); | |
| await router.replace({ name: "dashboard" }); | |
| } catch (err) { | |
| if (err instanceof InvalidCredentialsError) { | |
| toast.error(err.message); | |
| } else { | |
| throw err; | |
| } | |
| } finally { | |
| processingGoogle.value = false; | |
| } | |
| } | |
| async function facebookLogin(token: string): Promise<void> { | |
| processingFacebook.value = true; | |
| try { | |
| const accessToken = await issueFacebookGrantAccessToken({ | |
| token, | |
| }); | |
| await auth.authorize(accessToken); | |
| await router.replace({ name: "dashboard" }); | |
| } catch (err) { | |
| if (err instanceof InvalidCredentialsError) { | |
| toast.error(err.message); | |
| } else { | |
| throw err; | |
| } | |
| } finally { | |
| processingFacebook.value = false; | |
| } | |
| } | |
| async function passwordLogin(): Promise<void> { | |
| processingPassword.value = true; | |
| try { | |
| const accessToken = await issuePasswordGrantAccessToken({ | |
| username: email.value, | |
| password: password.value, | |
| }); | |
| await auth.authorize(accessToken); | |
| await router.replace({ name: "dashboard" }); | |
| } catch (err) { | |
| if (err instanceof InvalidOtpError) { | |
| await router.push({ name: "auth.login.otp" }); | |
| } else { | |
| toast.error(get(err, "message")); | |
| throw err; | |
| } | |
| } finally { | |
| processingPassword.value = false; | |
| } | |
| } | |
| </script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <template> | |
| <template v-if="entered"> | |
| <auth-title> | |
| {{ $t("auth.twoFactorAuthentication") }} | |
| <template #description> | |
| {{ $t("auth.yourAccountIsSecuredWithASecondAuthenticationMethod") }} | |
| <br /> | |
| {{ $t("auth.getTheSixDigitCodeFromYourMobileApplication") }} | |
| </template> | |
| </auth-title> | |
| <auth-sign-in-otp-form | |
| v-model:otp="otp" | |
| v-model:trusted="trusted" | |
| :processing="processingOtpLogin" | |
| @submit="passwordOtpLogin" | |
| /> | |
| </template> | |
| </template> | |
| <script lang="ts" setup> | |
| import { issuePasswordGrantAccessToken } from "@/lib/api/oauth"; | |
| import { | |
| InvalidCredentialsError, | |
| InvalidOtpError, | |
| } from "@/lib/api/oauth/errors"; | |
| import { useAuthStore } from "@/lib/store/auth"; | |
| import { useToast } from "@/lib/ui/hooks/toast"; | |
| import { inject, onBeforeMount, ref, type Ref } from "vue"; | |
| import { useI18n } from "vue-i18n"; | |
| import { useRouter } from "vue-router"; | |
| import AuthSignInOtpForm from "../../components/AuthSignInOtpForm.vue"; | |
| import AuthTitle from "../../components/AuthTitle.vue"; | |
| const auth = useAuthStore(); | |
| const router = useRouter(); | |
| const toast = useToast(); | |
| const i18n = useI18n(); | |
| const email = inject("email") as Ref<string>; | |
| const password = inject("password") as Ref<string>; | |
| const entered = inject("entered") as Ref<boolean>; | |
| const processingOtpLogin = ref(false); | |
| const otp = ref(""); | |
| const trusted = ref(false); | |
| const passwordOtpLogin = async () => { | |
| processingOtpLogin.value = true; | |
| try { | |
| const accessToken = await issuePasswordGrantAccessToken({ | |
| username: email.value, | |
| password: password.value, | |
| otp: otp.value, | |
| trusted: trusted.value, | |
| }); | |
| await auth.authorize(accessToken); | |
| await router.replace({ name: "dashboard" }); | |
| } catch (err) { | |
| if (err instanceof InvalidCredentialsError) { | |
| toast.error(err.message); | |
| await router.push({ name: "auth.login" }); | |
| } else if (err instanceof InvalidOtpError) { | |
| toast.error(i18n.t("auth.invalidOrExpiredOtpEntered")); | |
| } else { | |
| throw err; | |
| } | |
| } finally { | |
| processingOtpLogin.value = false; | |
| } | |
| }; | |
| onBeforeMount(async () => { | |
| if (!entered.value) { | |
| await router.push({ name: "auth.login" }); | |
| } | |
| }); | |
| </script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <template> | |
| <template v-if="entered"> | |
| <auth-title> | |
| {{ $t("auth.enterYourRecoveryCode") }} | |
| <template #description> | |
| {{ | |
| $t("auth.pleaseEnterTheRecoveryCodeYouSavedWhileSecuringYourAccount") | |
| }} | |
| </template> | |
| </auth-title> | |
| <auth-sign-in-otp-recovery-form | |
| v-model:recovery-code="recoveryCode" | |
| :processing="processing" | |
| @submit="submit" | |
| /> | |
| </template> | |
| </template> | |
| <script lang="ts" setup> | |
| import { issuePasswordGrantAccessToken } from "@/lib/api/oauth"; | |
| import { | |
| InvalidCredentialsError, | |
| InvalidOtpRecoveryCodeError, | |
| } from "@/lib/api/oauth/errors"; | |
| import { useAuthStore } from "@/lib/store/auth"; | |
| import { useToast } from "@/lib/ui/hooks/toast"; | |
| import { inject, onBeforeMount, ref, type Ref } from "vue"; | |
| import { useI18n } from "vue-i18n"; | |
| import { useRouter } from "vue-router"; | |
| import AuthSignInOtpRecoveryForm from "../../components/AuthSignInOtpRecoveryForm.vue"; | |
| import AuthTitle from "../../components/AuthTitle.vue"; | |
| const auth = useAuthStore(); | |
| const router = useRouter(); | |
| const i18n = useI18n(); | |
| const toast = useToast(); | |
| const entered = inject("entered") as Ref<boolean>; | |
| const email = inject("email") as Ref<string>; | |
| const password = inject("password") as Ref<string>; | |
| const processing = ref(false); | |
| const recoveryCode = ref(""); | |
| const submit = async () => { | |
| processing.value = true; | |
| try { | |
| const accessToken = await issuePasswordGrantAccessToken({ | |
| username: email.value, | |
| password: password.value, | |
| otpRecoveryCode: recoveryCode.value, | |
| }); | |
| await auth.authorize(accessToken); | |
| await router.replace({ name: "dashboard" }); | |
| } catch (err) { | |
| if (err instanceof InvalidCredentialsError) { | |
| toast.error(err.message); | |
| await router.push({ name: "auth.login" }); | |
| } else if (err instanceof InvalidOtpRecoveryCodeError) { | |
| toast.error(i18n.t("auth.invalidOtpRecoveryCodeEntered")); | |
| } else { | |
| throw err; | |
| } | |
| } finally { | |
| processing.value = false; | |
| } | |
| }; | |
| onBeforeMount(async () => { | |
| if (!entered.value) { | |
| await router.push({ name: "auth.login" }); | |
| } | |
| }); | |
| </script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment