I'm actually trying to implement Google reCaptcha in Nuxt App and I'm currently using "nuxt": "3.0.0-rc.11". I try to add this with nuxt2 or vue3 reCaptcha lib but unfortunately, I ended up with some error.
Anyone knows how I implement Google reCaptcha V2 in nuxt 3 App.
Here's my current implementation.
<template>
<form
action="?"
class="mt-8"
method="POST"
>
<div id="g-recaptcha"></div>
</form>
</template>
<script setup lang="ts">
useHead({
title: 'Contact',
titleTemplate: 'Gears - %s',
viewport: 'width=device-width, initial-scale=1, maximum-scale=1',
charset: 'utf-8',
meta: [
{name: 'description', content: 'Let’s discuss your work together.'}
],
// Here I Inject reCaptcha script using `useHead()` composable
script: [
{
hid: 'recaptcha',
src: 'https://www.google.com/recaptcha/api.js?trustedtypes=true?onload=onloadCallback&render=explicit',
defer: true
}
]
})
const isRecaptchaChecked = ref(false)
const form = reactive({
token: ''
})
function recaptchaCallback(token) {
isRecaptchaChecked.value = grecaptcha && grecaptcha.getResponse().length !== 0;
if (isRecaptchaChecked.value) {
form.token = token
}
}
onMounted(async () => {
await grecaptcha.render('g-recaptcha', {
'sitekey': runtimeConfig.siteKey,
'callback': recaptchaCallback
});
})
</script>
Problem #1 with this implementation
This implementation works fine but It's gave error ReferenceError: grecaptcha is not defined on initial load and if we reload the page the recaptcha works fine and even generate token
Problem #2 with this implementation
As I said this It's gave error ReferenceError: grecaptcha is not defined on initial load and when we reload the page this works fine. Now heading to problem 2, the other problem I face is after getting success recaptcha response If we change the page for example we want to go from /contact to /home the route change on browser URL bar but page is not changed.
Here's the live Website URL
Important Note
Before navigating to contact page please open devtool console and read my two problem and apply them you will understand better about my problem.
Thanks in advance.
ANNOUNCEMENT
I just found a way to implement reCAPTCHA v2 in nuxt3 but before that I want to tell the #nuxtjs/recapthca is not compatible with Nuxt3 and when #nuxtjs/recaptcha is support Nuxt3 then use #nuxt-recaptcha package instead of this solution.
Here's the Solution.
Related
developers,
I am working on a react native project that requires faceid login functionality.
Thanks to the libs and sample codes in the github repo, I implemented on my app very easily.
However, it displays the default bottom dialog when requiring the user to pass faceID auth in the android emulator.
react-native-biometrics
import ReactNativeBiometrics from 'react-native-biometrics';
//...
ReactNativeBiometrics.createSignature({
promptMessage: ' ',
payload: payload
})
.then((resultObject) => {
const { success, signature } = resultObject;
if (success) {
setMaskActive(true);
}
});
how can I remove the prompt dialog, but still keep calling ReactNativeBiometrics.createSignature() function?
Thank you.
I'm struggling to resolve an issue with the Google Sign In (GSI) library, where it refuses to allow users in a non-testing environment to proceed after clicking on "Sign In with Google". This works locally, and I have localhost/variations of localhost with a port added to Authorized JavaScript origins. I have also added my user-facing URLs to Authorized JavaScript origins, and yet Google does not seem to recognize the referring domain when it goes to accounts.google.com/gsi.
I've tried to debug the webpage locally to figure out what it thinks the given origin is. I've found references to a client_origin property within Google's gsi minified code, but I haven't been able to get anywhere when the value actually gets evaluated.
What I've tried:
Recreating the OAuth2 client ID from scratch
Clearing cookies/cache data from my browser
Using another browser
Creating a brand new Google Cloud Platform project
Other context:
I'm running a Next.js app on Azure App Services
It's hosted on a custom domain, although it doesn't appear to work with the provided Azure domain either
This works locally
Code:
import { Fragment, MutableRefObject, useEffect, useRef } from "react";
import getPublicRuntimeConfig from "lib/utils/get_public_runtime_config";
import Head from "next/head";
import Script from "next/script";
const { publicRuntimeConfig } = getPublicRuntimeConfig();
function handleGsiScriptLoad({
context = "signin",
signonButtonRef
}: {
context?: string;
signonButtonRef: MutableRefObject<HTMLDivElement>;
}) {
google.accounts.id.initialize({
client_id: publicRuntimeConfig.GOOGLE_SSO_CLIENT_ID,
context,
login_uri: publicRuntimeConfig.GAUTH_ENDPOINT,
// Necessary for the cookie to be accessible on the backend (subdomain)
state_cookie_domain: new URL(publicRuntimeConfig.MENTRA_PLATFORM_URL).host,
ux_mode: "redirect"
});
google.accounts.id.renderButton(signonButtonRef.current, {
size: "large",
text: context === "signup" ? "signup_with" : "signin_with",
theme: "outline"
});
}
interface Props {
context?: "signup" | "signin";
}
const GoogleSignon = (props: Props) => {
const signonButtonRef = useRef<HTMLDivElement>();
useEffect(() => {
handleGsiScriptLoad({ context: props.context, signonButtonRef });
}, [props.context]);
return (
<Fragment>
<Head>
{/* Necessary to set the correct origin URL from Azure */}
<meta name="referrer" content="no-referrer-when-downgrade" />
</Head>
<Script
onLoad={handleGsiScriptLoad}
src="https://accounts.google.com/gsi/client"
strategy="beforeInteractive"
/>
<div ref={signonButtonRef} />
</Fragment>
);
};
export default GoogleSignon;
Have I missed some step that prevents Google Sign In from recognizing my domain? Is there some nuance/weirdness with Azure App Service that just isn't documented anywhere?
I figured it out - I needed to provide the login_uri as an Authorized Origin as well, even though it's not actually originating from that URL. This is not documented anywhere, but it was the only difference between my local and production environment. Google signin works as expected now!
While trying to render a PDF, which gets served through our own API, the pdf.worker.js throws the following warning and the rendered PDF always keeps being completely white.
And I only see this (it's a wide PDF, but gets correctly rendered within the Demo):
Our Client application is served with angular, however I could not totally encapsulate the problem. With a simple and new angular application I was able to render a PDF File, served from our API but in my bigger client application the error above keeps occurring and I don't know why.
I'm using this Code to load the PDF, which inspired by this GitHub and this Blog Entry from Autodesk.
Autodesk.Viewing.Initializer({ env: 'Development', useADP: false }, () => {
const viewer = new Autodesk.Viewing.GuiViewer3D(
document.getElementById('forgeViewer'),
);
viewer.start();
const url =
'http://api.pdfFileToRender.pdf';
viewer.loadExtension('Autodesk.PDF').then(() => {
viewer.loadModel(
url,
{},
model => {
console.error('Success: ', model);
},
(errorCode, errorMessage, errorArgs) => {
console.error('Error Code: ', errorCode);
console.error('Error Msg: ', errorMessage);
console.error('Error Args: ', errorArgs);
},
);
viewer.loadExtension('Autodesk.Viewing.MarkupsCore');
viewer.loadExtension('Autodesk.Viewing.MarkupsGui');
});
});
The loadModel Function also calls the onSuccessCallback and I see "Success" in my Console.
For me it is not possible to integrate the PDF Extension into my Client App. Does anyone know a solution or have a hint for this, I gladly appreciate it.
It is also important for me, that the PDFs are rendered locally and are not uploaded to any Forge API.
For serving the Client Application I'm using Angular 11.2.7 and Typescript 4.1.5. I'm loading the ForgeViewer with the Version 7.36.0 but the Problem occurs also with other Versions.
For anyone interested, I could figure it out. Our own application was defining array prototype functions. However this is a problem for pdf.js which get's used by the PDF Extension from Forge.
The root problem was by defining array prototype functions like this:
Array.prototype.myFunction = function(...) {...}
We had to either exclude our own array functions or write it that way:
Object.defineProperty(Array.prototype, 'myFunction', {value: function(...) {...})
So, if you application defines array prototype function, use Object.defineProperty or don't use them at all. This seems to solve the Issue. Cheers.
I am a "newbie" to the Google Analytics API and I am trying to get the "Hello Analytics" example working.
I followed their steps
to create the test web page but I got no results.
When I go to my web page, I see the title, the "Sign in" button and the text area below where the result should appear. When I press "Sign in", that seems to work; the button changes to say "Signed In". However, no results appear.
I am using FireFox so I right-clicked on the text area and selected "Inspect Element"; this shows this error message:
Object { result: Object, body: "{ "error": { "code": 403, …",
headers: Object, status: 403, statusText: "Forbidden" }
I think this is a permission error but do not know how to correct it.
Here is my file HelloAnalytics.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello Analytics Reporting API V4</title>
<meta name="google-signin-client_id" content="959582115031-ardmn5vsir7kbcp0dme4d4n1p45bd649.apps.googleusercontent.com">
<meta name="google-signin-scope" content="https://www.googleapis.com/auth/analytics.readonly">
</head>
<body>
<h1>Hello Analytics Reporting API V4</h1>
<p>
<!-- The Sign-in button. This will run `queryReports()` on success. -->
<div class="g-signin2" data-onsuccess="queryReports"></div>
</p>
<!-- The API response will be printed here. -->
<textarea cols="80" rows="20" id="query-output"></textarea>
<script>
// Replace with your view ID.
var VIEW_ID = '92320289';
// Query the API and print the results to the page.
function queryReports() {
gapi.client.request({
path: '/v4/reports:batchGet',
root: 'https://analyticsreporting.googleapis.com/',
method: 'POST',
body: {
reportRequests: [
{
viewId: VIEW_ID,
dateRanges: [
{
startDate: '7daysAgo',
endDate: 'today'
}
],
metrics: [
{
expression: 'ga:sessions'
}
]
}
]
}
}).then(displayResults, console.error.bind(console));
}
function displayResults(response) {
var formattedJson = JSON.stringify(response.result, null, 2);
document.getElementById('query-output').value = formattedJson;
}
</script>
<!-- Load the JavaScript API client and Sign-in library. -->
<script src="https://apis.google.com/js/client:platform.js"></script>
</body>
</html>
I need to understand how to use the Google Analytics API to do simple queries.
FINALLY got it to work!
I was trying to use the API to get data for the Google sample site ("Google Merchandise Store"). I was trying to think of possible reasons for the permission error, and it occurred to me that maybe Google didn't allow Analytics API calls for that web site.
So I went through the effort of setting up my own test web site with Google's Javascript tracking code in it, then defining a new project, enabling the API for it, creating credentials (a client ID) and getting the view ID for my web site. With the new client ID and view ID in my HelloAnalytics.html page, it worked perfectly.
So my guess was correct: Google does NOT permit API calls to get data for its "Google Merchandise Store" sample website. They REALLY should mention this on their "quickstart" page because a "newbie" (like me) wouldn't know that!
I thought I should post my solution because I'm sure that somebody else will run into this problem in the future.
FYI- I have HelloAnalytics.html running on a web server. I am using free web space provided by my ISP.
I've built a Chrome Extension that takes a selection of text and when I right click and choose the context menu item, it sends that text to my Meteor app. This works fine, however, I can't figure out the process of using Oauth to authenticate users.
I'm using this package: https://github.com/eddflrs/meteor-ddp
Here is the JS within background.js (for Chrome Extension):
var ddp = new MeteorDdp("ws://localhost:3000/websocket");
ddp.connect().then(function() {
ddp.subscribe("textSnippets");
chrome.runtime.onMessage.addListener(function(message) {
ddp.call('transferSnippet', ['snippetContent', 'tag', snippetString]);
});
});
Here is the relevant portion of my other JS file within my Chrome Extension:
function genericOnClick(info) {
snippetString = [];
snippetString.push(info.selectionText);
var snippetTag = prompt('tag this thing')
snippetString.push(snippetTag);
chrome.runtime.sendMessage(snippetString);
}
And here is the relevant portion of my Meteor app:
'transferSnippet': function(field1, field2, value1, value2) {
var quickObject = {};
quickObject.field1 = value1[0];
quickObject.field2 = value1[1];
TextSnippets.insert({
snippetContent: value1[0],
tag: value1[1]
});
}
Basically I'm stuck and don't know how to go about making a DDP call that will talk to my Meteor app in order to authenticate a user
This question is a bit old, but if anyone is still looking for a solution. I had a similar problem that I was able to solve using the following plugin: https://github.com/mondora/asteroid. Here is an example of how to do it for twitter oauth:
https://github.com/mondora/asteroid/issues/41#issuecomment-72334353