Search code examples
javascriptgoogle-apps-scriptsvelte-3

Google captcha with svelte


So I had an issue with svelte and google Recaptcha API.

My main HTML file

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset='utf-8'>
    <meta name='viewport' content='width=device-width,initial-scale=1'>

    <title>Svelte app</title>

    <link rel='icon' type='image/png' href='/favicon.png'>
    <link rel='stylesheet' href='/global.css'>
    <link rel='stylesheet' href='/build/bundle.css'>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Bitter:400,700">
    <link rel="stylesheet" href="/css/styles.min.css">

    <script defer src='/build/bundle.js'></script>
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@9"></script>
</head>

<body>
</body>
</html>

My main.svelte

<script>
  import swal from "sweetalert";

  function verifyUser() {
    swal({
      title: "Please wait a minute!",
      text: "Do not close or exit this tab, we are currently verifying you...",
      icon: "info",
      backdrop: `rgba(0,0,0,1)`,
      showConfirmButton: false,
      allowOutsideClick: false,
      allowEscapeKey: false
    });
  }
</script>

<div>
  <div class="header-dark">
    <nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search">
      <div class="container">
        <a class="navbar-brand" href="/">QSP Human Verification Module</a>
        <button class="navbar-toggler" data-toggle="collapse">
          <span class="sr-only">Toggle navigation</span>
          <span class="navbar-toggler-icon" />
        </button>
      </div>
    </nav>
    <div class="container hero">
      <div class="row">
        <div class="col-md-8 offset-md-2">
          <h1 class="text-center">
            Please complete the Captcha challenge to continue to the server.
          </h1>

          <form action="" method="post">

            <div
              class="g-recaptcha"
              data-sitekey="key"
              data-callback={verifyUser}
             />
          </form>

        </div>
      </div>
    </div>
  </div>
</div>

Problem is that function just becomes string of itself and can't be executed using just "verifyUser" orverifyUser()returnsReCAPTCHA couldn't find user-provided function: verifyUser`

using {verifyUser} becomes string (for more https://prnt.sc/qhyc2w)

executing like that returns:

ReCAPTCHA couldn't find user-provided function: function verifyUser() {
        swal({
            title: "Please wait a minute!",
            text: "Do not close or exit this tab, we are currently verifying you...",
            icon: "info",
            backdrop: `rgba(0,0,0,1)`,
            showConfirmButton: false,
            allowOutsideClick: false,
            allowEscapeKey: false
        });
    }

rollup config

import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';

const production = !process.env.ROLLUP_WATCH;

export default {
    input: 'src/main.js',
    output: {
        sourcemap: true,
        format: 'iife',
        name: 'app',
        file: 'public/build/bundle.js'
    },
    plugins: [
        svelte({
            // enable run-time checks when not in production
            dev: !production,
            // we'll extract any component CSS out into
            // a separate file — better for performance
            css: css => {
                css.write('public/build/bundle.css');
            }
        }),

        // If you have external dependencies installed from
        // npm, you'll most likely need these plugins. In
        // some cases you'll need additional configuration —
        // consult the documentation for details:
        // https://github.com/rollup/plugins/tree/master/packages/commonjs
        resolve({
            browser: true,
            dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/')
        }),
        commonjs(),

        // In dev mode, call `npm run start` once
        // the bundle has been generated
        !production && serve(),

        // Watch the `public` directory and refresh the
        // browser on changes when not in production
        !production && livereload('public'),

        // If we're building for production (npm run build
        // instead of npm run dev), minify
        production && terser()
    ],
    watch: {
        clearScreen: false
    }
};

function serve() {
    let started = false;

    return {
        writeBundle() {
            if (!started) {
                started = true;

                require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
                    stdio: ['ignore', 'inherit', 'inherit'],
                    shell: true
                });
            }
        }
    };
}

Any how to properly pass the function?


Solution

  • im Rour- the guy from discord. I want to share solution here for others.

    <script>
    import { onMount, onDestroy } from 'svelte';
    
    function verifyUser() {/* your fun here */}
    
    onMount(() => {
      window.verifyUser = verifyUser;
    })
    
    onDestroy(() => {
      window.verifyUser = null;
    })
    </script>
    <!-- then pass the name of function 'verifyUser' just as string' -->
    <div class="g-recaptcha" data-sitekey="key" data-callback="verifyUser" />
    

    Thinking that data-callback is searching for name of global function, so we define verifyUser as global function in the browser by assign it to the window variable