Google API client compatibility with Google Chrome extensions - api

I'm working inside of a Google Chrome extension and I would like to use Google's Client API, https://apis.google.com/js/client.js, to retrieve a user's Google+ ID.
I've supplied the following values in my manifest.json:
"oauth2": {
"client_id": "[CLIENT ID].apps.googleusercontent.com",
"scopes": [
"https://www.googleapis.com/auth/plus.login",
"https://www.googleapis.com/auth/plus.me"
]
}
Providing these values allows me to successfully call chrome.identity.getAuthToken: http://developer.chrome.com/apps/identity.html
getAuthToken: function () {
chrome.identity.getAuthToken({
interactive: false
}, function (authToken) {
if (chrome.runtime.lastError) {
// User isn't signed into Google Chrome.
console.error(chrome.runtime.lastError.message);
}
});
}
Once I have an auth token, I'm able to issue an AJAX request and successfully get my info:
$.ajax({
url: 'https://www.googleapis.com/plus/v1/people/me',
headers: {
'Authorization': 'Bearer ' + authToken
},
success: function (response) {
console.log("Received user info", response);
},
error: function (error) {
console.error(error);
}
});
None of this uses the aforementioned Google Client API, though. It would be nice to leverage that instead, but I'm wondering if it is not meant for Google Chrome extensions. I'm able to at least get things sort of working like so:
GoogleAPI.auth.authorize({
client_id: '[CLIENT ID].apps.googleusercontent.com',
scope: 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.me',
// Set immediate to false if authResult returns null
immediate: true
}, function(){
GoogleAPI.client.load('plus', 'v1', function () {
var request = GoogleAPI.client.plus.people.get({
'userId': 'me'
});
request.execute(function (response) {
console.log("Response:", response);
});
});
But I've already specified these values in my manifest -- so it seems a bit odd to re-refrence them. I could load my manifest and parse it, but I've already got something successfully working above.
Additionally, you have to call GoogleAPI.client.setApiKey to use Google's stuff. This works on a development environment because I am able to whitelist my machine's IP, but this would not work in a production environment as there will be many clients connecting.
So, should Google's Client API not be used within Google Chrome extensions?

Related

Google ReCaptcha API doesnt work properly on my frontend

When I try to make the call from the browser it doesnt work properly
This is the response I get in browser
It is supposed to be like this:
{
"success": true|false,
"challenge_ts": timestamp, // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
"hostname": string, // the hostname of the site where the reCAPTCHA was solved
"error-codes": [...] // optional
}
I'm using vue-recaptcha library on vue3.
<VueRecaptcha
ref="recaptcha"
sitekey="my_key"
#verify="onVerify"
/>
This is the fetch method I use to make the call to google recaptcha api
function onVerify(token) {
fetch(
`https://www.google.com/recaptcha/api/siteverify?secret=${secret_key}&response=${token}`,
{
method: 'POST',
}
)
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error('There was an error!', error);
});
}
The thing is when i try the same call in postman it works as it should and responds with the following object:
{
"success": true,
"challenge_ts": "2023-02-07T13:20:44Z",
"hostname": "localhost"
}

Unexpected behaviour of payment_intent api with GET and POST method

I am using the payment_intent API to generate payment intent for payment sheet initialization.
As per the document, payment_intent is the POST method. Showing different errors in android and iOS.
https://stripe.com/docs/api/payment_intents/create
Note:- It's working in postman not working on mobile.
Case 1 Android
It is not working with the POST method. It worked with the GET method this is weird.
Case 2 iOS
It is not working with the GET and POST methods both.
With POST received the following error
_response": "{
\"error\": {
\"code\": \"parameter_missing\",
\"doc_url\": \"https://stripe.com/docs/error-codes/parameter-missing\",
\"message\": \"Missing required param: amount.\",
\"param\": \"amount\",
\"type\": \"invalid_request_error\"
}
}
With GET method received the following error
"_response":"resource exceeds maximum size"
End Point URL:-
let data = JSON.stringify({
customer: customerId,
currency: 'inr',
amount: 1000,
'automatic_payment_methods[enabled]': 'true',
});
let config = {
method: 'GET',
url: 'https://api.stripe.com/v1/payment_intents',
headers: {
Authorization:
'Bearer sk_test_DmXI7Jw1PnJAWYps3iCpvKkttIGX00pPfGLTjj',
'Content-Type': 'application/x-www-form-urlencoded',
},
data: data,
};
axios(config)
.then(function (response) {
console.info(JSON.stringify(response));
})
.catch(function (error) {
console.error('-----', error.response);
});
Following this document
https://stripe.com/docs/payments/accept-a-payment?platform=react-native&ui=payment-sheet#react-native-flowcontroller
https://stripe.com/docs/api/payment_intents/create
Added snack URL to reproduce the issue.
https://snack.expo.dev/#vishaldhanotiya/stripe-payment-intent
Error Log
To clarify a few things:
1/ You shared your (test mode) secret key in your code snippet, please delete that and roll your API keys (https://stripe.com/docs/keys#keeping-your-keys-safe).
2/ Your iOS/Android apps should not be making requests to Stripe's APIs directly with your secret API key, as that means you are bundling your secret key with your apps which means anyone running your app has access to your secret key.
Instead, you need to make requests from your iOS app to your server and your server should use Stripe's server-side libraries to make requests to Stripe's APIs. Your iOS/Android apps can only make requests with your publishable key.
3/ The PaymentIntent endpoint supports both POST and GET. You can create a PaymentIntent by POSTing to the /v1/payment_intents endpoint, you retrieve a single PaymentIntent with a GET to the /v1/payment_intents/:id endpoint and you list PaymentIntents with a GET to the /v1/payment_intents endpoint.
4/ The error in your POST request shows "Missing required param: amount." so you need to debug your code to make sure the amount parameter is getting through. You can use Stripe's Dashboard Logs page https://dashboard.stripe.com/test/logs to debug what parameters your code is sending to Stripe's API.
Finally, I found a solution. The issue occurred because I am send parameters without encoding.
I found a solution from this link
https://stackoverflow.com/a/58254052/9158543.
let config = {
method: 'post',
url: 'https://api.stripe.com/v1/payment_intents',
headers: {
Authorization:
'Bearer sk_test_51J3PfGLTjj',
'Content-Type': 'application/x-www-form-urlencoded'
}
};
let paymentDetail = {
customer: 'cus_MSiYLjtdaJPiCW',
currency: 'USD',
amount: 100,
'automatic_payment_methods[enabled]': true
};
let formBody: any = [];
for (let property in paymentDetail) {
let encodedKey = encodeURIComponent(property);
let encodedValue = encodeURIComponent(paymentDetail[property]);
formBody.push(encodedKey + '=' + encodedValue);
}
formBody = formBody.join('&');
const result = await axios
.post('https://api.stripe.com/v1/payment_intents', formBody, {
headers: config.headers
})
.then(function (response) {
console.info(JSON.stringify(response));
})
.catch(function (error) {
console.error('-----', error.response);
});

Problems to get a refresh token using vue, nuxt and keycloak

I'm doing a project with vue, nuxt and keycloak as server for token, axios as http client and #nuxtjs/auth-next module for keycloak access.
I'm using a public client so I don't have a secret key which is the most recommended.
The part of getting the token and talking to the backend is working.
But as it is a public client it has no refresh token.
Searching the internet, a recommendation would be to post from time to time to the keycloak /token endpoint, passing the current token, to fetch a new token.
To perform this post, it doesn't work to pass json, having to pass application/x-www-form-urlencoded.
But it generates an error saying that the parameter was not passed.
On the internet they recommended passing it as url string, but then it generates an error on the keycloak server, as a parameter that is too long, because of the current token that is passed.
Below is the code used to try to fetch a new token.
This code is being called on a test-only button.
If anyone can help, I appreciate it.
const token = this.$auth.strategy.token.get()
const header = {
"Content-Type": "application/x-www-form-urlencoded"
}
const body = {
grant_type: "authorization_code",
client_id: "projeto-ui",
code: token
}
this.$axios ( {
url: process.env.tokenUrl,
method: 'post',
data: body,
headers: header
} )
.then( (res) => {
console.log(res);
})
.catch((error) => {
console.log(error);
} );
Good afternoon people.
Below is the solution to the problem:
On the keycloak server:
it was necessary to put false the part of the implicit flow.
it was necessary to add web-origins: http://localhost:3000, to allow CORS origins.
In nuxt.config.js it was necessary to modify the configuration, as below:
auth: {
strategies: {
keycloak: {
scheme: 'oauth2',
...
responseType: 'code',
grantType: 'authorization_code',
codeChallengeMethod: 'S256'
}
}
}

How to properly use passport-github for REST API authentication?

I am building a vue.js client which needs to be authenticated through github oauth using an express server. It's easy to do this using server side rendering but REST API has been troublesome for me.
I have set the homepage url as "http://localhost:3000" where the server runs and I want the authorization callback url to be "http://localhost:8080" (which hosts the client). I am redirecting to "http://localhost:3000/auth/github/redirect" instead, and in its callback redirecting to "http://localhost:8080". The problem I am facing is that I am unable to send user data to the vuejs client through res.redirect. I am not sure if I am doing it the right way.
router.get("/github", passport.authenticate("github"));
router.get(
"/github/redirect",
passport.authenticate("github", { failureRedirect: "/login" }),
(req, res) => {
// res.send(req.user);
res.redirect("http://localhost:8080/"); // req.user should be sent with this
}
);
I have implemented the following approach as a work around :-
A route that returns the user details in a get request :
router.get("/check", (req, res) => {
if (req.user === undefined) {
res.json({});
} else {
res.json({
user: req.user
});
}
});
The client app hits this api right after redirection along with some necessary headers :
checkIfLoggedIn() {
const url = `${API_ROOT}auth/check/`;
return axios(url, {
headers: { "Content-Type": "application/json" },
withCredentials: true
});
}
To enable credentials, we have to pass the following options while configuring cors :
var corsOption = {
origin: true,
credentials: true
};
app.use(cors(corsOption));

Cancel all Google/Firebase messaging subscriptions

I just rewrote my firebase cloud messaging code for my web API and now use a Cloud Function to handle the subscriptions, or at least that is the theory.
Where can I go to cancel any existing subscriptions so that I can check that what seems now to be working, actually is (and that is not some hangover from before that is giving the impression of working).
This is all on a development instance of Firebase so I can delete whatever I want. I set up the subscriptions with the following code, which may or may not be coreect, but I think it means I need to look on Google rather than Firebase, but I can't find anything
let token = req.query.token;
let topic = "presents";
let uri = `https://iid.googleapis.com/iid/v1/${token}/rel/topics/${topic}`;
// Make the request to Google IID
var myHeaders = {
"Content-Type": "application/json",
Authorization: "key=" + secrets.devKey
};
var options = {
uri: uri,
method: "POST",
headers: myHeaders,
mode: "no-cors",
cache: "default"
};
rp(options)
.then(function(response) {
// console.log("rp success", response);
res.status(200).send({
msg: "Ok from Simon for " + token,
payload: response}
);
})
.catch(function(err) {
console.log("[fbm.registerForUpdates] Error registering for topic", err.message);
res.status(500).send(err);
});
The Firebase documentation seems to be incomplete on this topic. Playing around showed the following (valid at least at the time of writing, verified w/ Postman):
POST https://iid.googleapis.com/iid/v1/IID_TOKEN/rel/topics/TOPIC_NAME request creates a subscription for a topic & token
GET https://iid.googleapis.com/iid/info/IID_TOKEN?details=true request lists all subscribed topics for a token
DELETE https://iid.googleapis.com/iid/v1/IID_TOKEN/rel/topics/TOPIC_NAME request removes a subscription for a topic for a token
DELETE https://iid.googleapis.com/v1/web/iid/IID_TOKEN request removes all subscriptions for a token
On all these requests the header 'Authorization: key=YOUR_SERVER_KEY' needs to be set.
Sample output from a GET request:
{
"connectDate": "2018-10-06",
"application": "com.chrome.macosx",
"subtype": "wp:https://192.168.0.196:8020/#9885158F-953C-48BC-BCF5-38ABF2F89-V2",
"scope": "*",
"authorizedEntity": "30916174593",
"rel": {
"topics": {
"sensorUpdate": {
"addDate": "2018-10-07"
}
}
},
"connectionType": "WIFI",
"platform": "BROWSER"
}