Coder Social home page Coder Social logo

Comments (6)

vandelpavel avatar vandelpavel commented on July 20, 2024 4

Yeah but still remais undefined. Check #561

from vue-recaptcha-v3.

cloedu87 avatar cloedu87 commented on July 20, 2024 2

you're right @averri, there is a implementation and/or documentation issue... but you can use it like this:

import { useReCaptcha } from 'vue-recaptcha-v3';

export default defineComponent({
  name: 'BlaComponent',
  setup() {
    const reCaptcha = useReCaptcha();

    async function recaptcha() {
      await reCaptcha.recaptchaLoaded();

      const token = await reCaptcha.executeRecaptcha('submit');

      return await verifyRecaptcha(token);
    }

    return {
      recaptcha,
    }

from vue-recaptcha-v3.

jdmr avatar jdmr commented on July 20, 2024

@vandelpavel you just need to verify it's there:
`
import { useReCaptcha } from 'vue-recaptcha-v3';

export default defineComponent({
name: 'BlaComponent',
setup() {
const reCaptcha = useReCaptcha();

async function recaptcha() {
  if (!reCaptcha) {
      return alert('could not get recaptcha');
  }
  await reCaptcha.recaptchaLoaded();

  const token = await reCaptcha.executeRecaptcha('submit');

  return await verifyRecaptcha(token);
}

return {
  recaptcha,
}

});
`

from vue-recaptcha-v3.

benschool avatar benschool commented on July 20, 2024

For anyone looking through this using <script setup>, I was misunderstanding how to implement the composition API into my project.

All composition logic should be in the setup. In my case i am using apollo, and needed to send the token as a header and found doing it like this works (Obviously there is a bunch of stuff that won't be applicable to your project but take it as an example)

<template>
  <div class="login">
    <LoginForm
      @submit="(formData: QueryLoginWithLocalArgs) => {
            clearErrors();
            loginArgs = formData;
            if (validateForm(formData)) {
              login();
            }
          }"
      submitCopy="Login"
      :fields="[
        {
          key: 'email',
          type: InputType.TextInput,
          field: {
            value: '',
            placeholder: '[email protected]',
          },
          required: true,
          label: 'Email',
          error: errors.email,
        },
        {
          key: 'password',
          type: InputType.TextInput,
          field: {
            value: '',
            placeholder: '**********',
            isHidden: true,
            minLength: {
              limit: 8,
              show: true,
            },
          },
          required: true,
          label: 'Password',
          error: errors.password,
        },
      ]"
    />
    <div class="recaptcha-disclaimer">
      This site is protected by reCAPTCHA and the Google
      <a
        href="https://policies.google.com/privacy"
        target="_blank"
        rel="noopener noreferrer"
      >
        Privacy Policy
      </a>
      and
      <a
        href="https://policies.google.com/terms"
        target="_blank"
        rel="noopener noreferrer"
      >
        Terms of Service
      </a>
      apply.
    </div>
    <div class="alternative-login">
      <div class="alternative-login__text">Or continue with</div>
      <div class="alternative-login__buttons">
        <BaseButton
          @click="emitDismiss"
          :type="ButtonType.Ghost"
          :outline="true"
        >
          <VSvg svg="Steam" />
          <span>Steam</span>
        </BaseButton>
        <BaseButton
          @click="emitDismiss"
          :type="ButtonType.Ghost"
          :outline="true"
        >
          <VSvg svg="MetaMask" />
          <span>Metamask</span>
        </BaseButton>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { useReCaptcha } from "vue-recaptcha-v3";
import { InputType } from "../../Form/types";
import { LoginEmits, LoginData, LoginFormKeys } from "./types";
import { LoginFormSchema } from "./schema";
import { ButtonType } from "../../Button/types";
import { ref } from "vue";
import { useUserStore } from "../../../stores/user/user";
import { QueryLoginWithLocalArgs } from "../../../graphql/types";

const reCaptchaInstance = useReCaptcha();

async function recaptcha() {
  await reCaptchaInstance?.recaptchaLoaded();
  return await reCaptchaInstance?.executeRecaptcha("login");
}

defineEmits<LoginEmits>();

const loginArgs = ref<QueryLoginWithLocalArgs>({
  email: "",
  password: "",
});

const formError = ref<string | undefined>(undefined);
const userId = ref<string>("");
const loginHeaders = ref<{ ["x-captcha-token"]?: string }>({});

const {
  load: executeLogin,
  onResult: onLoginResult,
  onError: onLoginError,
} = useLoginWithLocalLazyQuery(loginArgs, {
  context: {
    headers: loginHeaders,
  },
});

const {
  load: executeGetUser,
  onResult: onGetUserResult,
  onError: onGetUserError,
} = useGetUserLazyQuery({ getUserId: userId.value });

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const login = async () => {
  const token = await recaptcha();
  loginHeaders.value = token === undefined ? {} : { "x-captcha-token": token };
  await executeLogin();

  onLoginResult(({ data: { loginWithLocal } }) => {
    if ("type" in loginWithLocal) {
      switch (loginWithLocal.type) {
        case "CAPTCHA_FAILED":
          formError.value = "Captcha Error";
          break;
        case "INVALID_CREDENTIALS":
          formError.value = "Invalid Credentials";
          break;
        case "UNKNOWN":
        case "BLOCKED":
          formError.value = "Unknown Error, please try again later";
          break;
      }
      return;
    } else {
      userId.value = loginWithLocal.userId;
      hydrateUserStore();
    }
  });

  onLoginError((error) => {
    console.log(error);
  });
};

const hydrateUserStore = async () => {
  await executeGetUser();

  onGetUserResult(({ data: { getUser } }) => {
    if ("type" in getUser) {
      switch (getUser.type) {
        case "UNKNOWN":
          formError.value = "Unknown Error, please try again later";
          break;
      }
    } else {
      console.log(getUser);
      useUserStore().hydrateUser(getUser);
    }
  });

  onGetUserError((error) => {
    console.log(error);
  });
};
</script>

<script lang="ts">
import { defineComponent } from "vue";
import BaseButton from "../../Button/BaseButton.vue";

import Form from "../../Form/Form.vue";
import Svg from "../../Svg/Svg.vue";
import { useLoginWithLocalLazyQuery } from "../../../graphql/features/authentication/queries/index.generated";
import { useGetUserLazyQuery } from "../../../graphql/features/user/queries/index.generated";

export default defineComponent({
  name: "Login",
  components: {
    BaseButton,
    LoginForm: Form,
    VSvg: Svg,
  },
  data(): LoginData {
    return {
      errors: {
        email: undefined,
        password: undefined,
      },
    };
  },
  methods: {
    emitDismiss() {
      this.$emit("dismiss");
    },
    clearErrors() {
      Object.keys(this.errors).forEach((key) => {
        this.errors[key as LoginFormKeys] = undefined;
      });
    },
    validateForm(values: QueryLoginWithLocalArgs): boolean {
      const parsedSchema = LoginFormSchema.safeParse(values);
      if (parsedSchema.success) return true;

      parsedSchema.error.issues.forEach((issue) => {
        this.errors[issue.path[0] as LoginFormKeys] = issue.message;
      });

      return false;
    },
  },
});
</script>

from vue-recaptcha-v3.

samweru avatar samweru commented on July 20, 2024

@averri anything changed? This issue has been open for quite sometime.

from vue-recaptcha-v3.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.