Why would a server deny a request? - google-chrome-extension

I am working on a chrome extension that creates an Anki card and adds it to my desk.
Right now am I trying to get the request to work using the Anki API.
For some reason the server is denying my request.
Here is my code (JavaScript) to create a card and send it as a request to the localhost:
async function createCard() {
// Set the Anki API endpoint URL
const baseURL = 'http://localhost:8765';
// Set the Anki API action, version and params
const card = {
"action": "addNote",
"version": 6,
"params": {
"note": {
"deckName": "Default",
"modelName": "Basic",
"fields": {
"Front": "front content",
"Back": "back content"
},
"options": {
"allowDuplicate": false,
"duplicateScope": "deck",
"duplicateScopeOptions": {
"deckName": "Default",
"checkChildren": false,
"checkAllModels": false
}
}
}
}
};
// Send the request to the Anki API
try {
const response = await fetch(baseURL, {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(card)
});
// Check the status code of the response
if (response.ok) {
console.log('Card created successfully');
} else {
console.error(`Error creating card: ${response.statusText}`);
}
} catch (error) {
console.error(`Error creating card: ${error}`);
}
}
(The card by now is hardcoded.)
When I execute this code I get 2 errors thrown by chrome:
POST http://localhost:8765/ net::ERR_ABORTED 403 (Forbidden)
Error creating card:
The first error happens on the fetch function
and the second error at "console.error('Error creating card: ${response.statusText}');"
I suggest that the second error appears due to the first one.
Since I am new to computer science, all I tried so far is checking the logs of ANKI to find information about the error, but I couldn't find something. I tried different syntax to create the card since I pass this into the fetch function where the error occurs.
The localhost is running while I am working on this, so the server is accessible.

My solution is setting the webCorsOriginList config of AnkiConnect as "*"
"webCorsOriginList": ["*"]
It will allow CORS for all domains.

Related

Getting "EHOSTUNREACH" when trying to connect to API using Axios + Express.js

I started playing around with the Philips Hue Bridge API by sending it requests using Postman. I was able to authenticate myself, create a user and even successfully turn lights on or off.
Conclusion: I am able to reach the API.
Next I made a mini test javascript file to do the exact same using Node.js and axios#0.21.4. When I try the following code everything works and I receive the expected JSON responses:
const axios = require('axios')
axios({
method: 'GET',
url: 'http://philips-hue.local/api/BYLCIlxABzz2eDHAxx70T'
})
.then(({data}) => {
console.log('------> AXIOS RES: ', data)
})
.catch((err) => {
console.log('------> AXIOS ERR: ', err)
})
Conclusion: Axios is able to communicate with the API.
Next I wanted to build this into an Express.js endpoint. However when I try to use the same code inside of express#4.17.1 I get an error:
router.route('/getlights').get((req, res) => {
axios({
method: 'GET',
url: 'http://philips-hue.local/api/BYLCIlxABzz2eDHAxx70T/lights'
})
.then(({data}) => {
console.log('------> AXIOS RES: ', data)
res.json({
state: 'SUCCESS',
data
})
})
.catch((err) => {
console.log('------> AXIOS ERR: ', err)
res.json({
state: 'ERROR',
err
})
})
})
Response:
{
"state": "ERROR",
"err": {
"message": "connect EHOSTUNREACH 192.168.0.107:80",
"name": "Error",
"stack": "Error: connect EHOSTUNREACH 192.168.0.107:80\n at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)",
"config": {
"url": "http://philips-hue.local/api/BYLCIlxABzz2eDHAxx70T/lights",
"method": "get",
"headers": {
"Accept": "application/json, text/plain, */*",
"User-Agent": "axios/0.21.1"
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1
},
"code": "EHOSTUNREACH"
}
}
I started troubleshooting the problem by first trying to changing the URL to a random online place holder like http://jsonplaceholder.typicode.com/posts/1 just to see if I could establish any connection at all. This actually worked right away.
This is where I got really confused. Why am I able to successfully communicate with the bridge using Postman or Axios in a javascript file, but NOT able to connect with it when the same Axios code is used by express. The problems seems to occur only when using both axios and express to connect to the bridge API.
I have already tried retesting this with node-fetch and 3 other versions of Axios. All tests failed the exact same way. The code by itself can always connect to the API but once the code is being called by express it causes the EHOSTUNREACH error.
I ran out of ideas on how to further google this issue since I am not sure what exactly is causing the problem (express and/or axios and/or bridge). Any trouble shooting ideas or google keywords are also very welcome. :)
I had the same error, for some reason the ip address of my hue bridge had changed so I went into the hue app on my smartphone and copied the new ip address. IDK if this is helpfull, im pretty new here.
I had the same error since yesterday, and couldn't find solution. What actually caused mine was, there was a bearer token on the 3rd party api I called and i also pass it through the header as well.
So it was removed and pass the token through header and it works fine.
UPDATE: error keeps showing up if send another request.
The solution i found was to use request.
const request = require('request');
const headers = {
'Content-Type': 'application/json',
'token': `${token}`
};
const data = {
username : 'username'
}
let options = {
method: 'POST',
url: 'url',
port: 443,
headers: headers,
body: data,
json: true
};
request(options, async (error, res, body) => {
if (error) {
console.log({error});
return response.status(500).json({
status: false,
message: "Error occured"
});
} else {
console.log({body});
return response.status(201).json({
message: "success"
});
}
});

PUT API request returning JSON body error

Im trying to update a distribution list by sending a put request, when I run this code and test it in postman by giving it a JSON body I get this error in my node.js terminal stating SyntaxError: Unexpected end of JSON input ... any idea what I should change?
My PUT API request
app.put("/api/Dls/Add/:groupId" , (req, res) => {
const response = {
success: false
};
if (Authorized.myToken) {
response.success = true;
response.data = {};
var options = {
method: 'PUT',
url: 'https://SomeAPI.com/' + req.params.groupId,
headers:
{
Accept: 'application/json',
Authorization: 'Bearer' + ' ' + Authorized.myToken
},
body: JSON.stringify(req.body)
};
request(options, function (error, response, body){
if (error) {
console.log(error);
return;
}
const data = response.body;
const dls = JSON.parse(data)
return res.json(dls);
});
}
});
JSON body I'm passing through postman to test the API call
{
"groupId": "123456789",
"SomeField1": null,
"SomeField2": "xxxxxxxxx",
"SomeField3": true,
"SomeField4": "xxxxxxxxx",
"SomeField5": "xxxxxxxxx",
"SomeField6": [
"xxxxxxxxx"
],
"SomeField7": "xxxxxxxxx",
"SomeField8": "xxxxxxxxx",
"SomeField9": "xxxxxxxxx",
"SomeField10": "xxxxxxxxx",
"SomeField11": [],
"SomeField12": "xxxxxxxxx",
"SomeField13": null,
"SomeField14": false,
"SomeField15": ["xxxxxxxxx"]
}
Any feedback is appreciated!
If the JSON that you posted here is the real one that you pass via postman then, it is not the valid JSON as you have the same name properties. When I say valid it means you get something like this after posting to the endpoint.
{
"groupId": "123456789",
"SomeField": [
"xxxxxxxxx"
]
}
Request npm package is also deprecated so it is better to not use it and replace it with something like Axios. TBH I did not see any error in the code that causes the error that you mentioned, do you have access to the API to check the logs? Maybe something went wrong on the https://SomeAPI.com/ endpoint.
I figured out what the issue was, I needed to add the .end to the return statement
ex. return res.status(200).end()

Firebase Cloud Functions: Requests from referer <empty> are blocked. - PERMISSION_DENIED

I am not sure why the following code is throwing google api key permission denied.
I have the api or service enabled both in firebase console and google console.
export async function createJobDynamicLink(job){
if(job.jobStatus !== 'approved' || (job.dynamicLink).length > 2){
console.log('Dynamic link already exist!');
return false;
}
console.log(dynamic_links);
console.log(dynamic_links_key);
// Firebase web api key logs just fine
const options = {
method: 'POST',
uri: `https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=${dynamic_links_key}`,
body: {
"longDynamicLink": makeDynamicLongLink(job)
},
json: true
};
return await requestpromise(options)
.then(function (parsedBody) {
console.log(parsedBody);
return parsedBody.shortLink;
})
.then((shortLink) => {
//post.shareUrl = shortLink;
console.log('short link: ' + shortLink);
//return event.data.ref.set(post);
return shortLink;
})
}
export async function makeDynamicLongLink(job) {
return buildUrl(`${dynamic_links}`, {
queryParams: {
link: `https://app.com/jobs/${slugify(job.jobTitle)}-${job.id}`,
apn: "com.app.appe",
ibi: "com.app.app",
dfl: "https://app.com",
st: job.jobTitle,
}
});
}
Is something wrong with the way I am doing the request using request-promise?
StatusCodeError: 403 - {
"error": {
"code": 403,
"message": "Requests from referer <empty> are blocked.",
"status": "PERMISSION_DENIED",
"details": [{
"#type": "type.googleapis.com/google.rpc.Help",
"links": [{
"description":"Google developer console API key",
"url": "https://console.developers.google.com/project/904573jjwj/apiui/credential"
}]
}]
}
}
Go to the Google API Credentials https://console.developers.google.com/apis/credentials and see if there is any restriction on your API Key you're using.
If it is restricted by HTTP referrers, then add your website domain to it and add the Referrer header like the above answer.
Although in your use case, None or IP address restriction is a better choice.
Because you are invoking your function from a node.js environment, the HTTP Header Referer isn't being set. When you create requests through a browser, the browser will automatically fill this field for you.
You can get a suitable referrer value using:
"https://" + process.env.GCLOUD_PROJECT + ".cloudfunctions.net/createJobDynamicLink"
// becomes "https://your-project-id.cloudfunctions.net/createJobDynamicLink"
This generated URL isn't callable, because it doesn't start with a region, but it means you now have a URL that can be used to identify that the call is coming from a Cloud Function.
To use it, add it to your request-promise options object.
const options = {
method: 'POST',
uri: `https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=${dynamic_links_key}`,
body: {
"longDynamicLink": makeDynamicLongLink(job)
},
headers: {
"Referer": "https://" + process.env.GCLOUD_PROJECT + ".cloudfunctions.net/createJobDynamicLink"
},
json: true
};
Note: I'd use request-promise-native instead of request-promise - same API but skips loading Bluebird.
In my case i had
<meta name="referrer" content="no-referrer">
in the head so the referer was not being sent

How do I properly send parameters and headers for swagger client get?

Currently checking out https://www.npmjs.com/package/swagger-client. The docs are a bit confusing to me.
I intend to hit a URL like www.mysite.com/topic/:topicName
I tried a few things like this:
const authHeaders = {
'X-Api-Key': 'mykey',
Authorization: `Bearer mytoken`,
};
const topic = await client.apis.Topic.getTopic({
headers: authHeaders,
parameters: {
topicName: 'myName'
}
});
I can't seem to figure the right way to send headers and fill in the variable from the swagger docs to form the URL. I'd seen examples where the headers are the first argument so I also had tried
const topic = await client.apis.Topic.getTopic(authHeaders, {
parameters: {
topicName: 'myName'
}
});
When I look at the docs for the word headers, they just talk about setting up the initial client. I figure making it send the auth headers every time is another good solution so I'm kind of looking for both ways (since either can make sense depending on the header).
Using the swagger-client is a little different that a regular http client because it follow exactly your swagger file, you will have to provide the parameters that your swagger spec describes.
for swagger client v3, this format works for me:
Swagger({
url: "www.example.org/swagger.json",
authorization: {
// This must be described in your swagger file, if not, will be ignored.
// See https://swagger.io/docs/specification/authentication/bearer-authentication/
bearerAuth: {type: 'apiKey', 'in': 'header', name: 'Authorization'}
}
}).then(client => {
client.apis.Topic.getTopic({
// The parameters need to be described in the swagger file, or will be ignored.
// Also make sure that the getTopic operation describes that uses the bearerAuth
// Or swagger-client will not send the Auth credentials.
topicName: "myName"
}).then(response => {
// Do magic.
})
});
The swagger portion for your getTopic operation should be similar to this:
{
"/rest/3/topic/{topicName}": {
"tags": ["topic"]
"operationId": "getTopic"
"get": {
"parameters": [
{
"name": "topicName", "in": "path", "required": true, "type": "string"
}
],
"security": { "basicAuth": "global" }
}
}
}

PouchDB basic auth does not work with sync gateway

When I try to sync from PouchDB to couchbase server using sync gateway I am getting following error:
XMLHttpRequest cannot load http://localhost:4984/test/. Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
I try to set the header even then I am not able to get rid of this error.
Here is my sync gateway config file
sync-gateway-config.json::
{
"log":["*"],
"databases": {
"buildercycle": {
"server":"http://localhost:8091",
"bucket": "default",
"users": {
"GUEST": {
"disabled": false,
"admin_channels": ["*"]
}
},
"sync":`function(doc, oldDoc) {
if (doc.type == "sports"){
channel(doc.type);
access(doc.owner,doc.type);
} else {
channel(doc.type);
access(doc.owner,doc.type);
}
}`
}
},
"CORS": {
"Origin": ["http://localhost:8000","http://localhost:8083", "http://localhost:4985"],
"LoginOrigin": ["http://localhost:8000","http://localhost:8083","http://localhost:4985"],
"Headers": ["Content-Type"],
"MaxAge": 17280000
}
}
I am trying to sync my PouchDB in following way:
remoteCouch="http://"+user+":"+pass+"#localhost:4984/buildercycle";
console.log(remoteCouch);
var opts = {live: true,withCredentials: true};
db.sync(remoteCouch,opts,'error');
i am passing user(user1) and password(password) which is defined in following sync_gateway admin URL
http://localhost:4985/_admin/db/test/users
I am unable to pin point the error, Please help
Add authorization in headers
"Headers": ["Content-Type","authorization"],
I think cors header is not getting set properly in your case.

Resources