I'm trying to add jest acceptance testing into an API repo (currently there are jest unit tests). The app is serverless aws. I'm working on getting a rough working p.o.c. API test against a staging url and I've put together this test file but it isn't working as expected and I don't have details to go on. I'd like to know how to return more details for a failure or what I'm missing to get it to hit the route as expected.
I'm returning 500 errors, but no real extra details. If I input an empty/invalid jwt token - still returns 500. If I remove the expect(response.status).toEqual(200); it "passes" but the console.log("blah blah blah here" + response); fails to show the response (or the "blah blah blah" for that matter). How can I return more details to see what I may be missing? Or adjust my request so it successfully hits that route and returns a better response?
My auth_impersonation p.o.c. test
import { agent as request } from 'supertest';
import express = require('express');
describe('Impersonate SE merchant', () => {
let app: express.Application = express();
let jwtToken = 'string I'm putting in manually for now';
it('returns a valid access token', async () => {
// within it block attempts here (below)
const response = await request(app)
.get('full staging url string here')
.auth(jwtToken, {type: 'bearer'});
console.log("blah blah blah here" + response);
// expect(response.status).toEqual(200);
})
});
Here's how the request looks in postman where the route works
Another go of the postman request, headers
Related
I have an Azure search index called users that has CORS configured to * (for now) to allow all origins. When I make a GET request to it programmatically using fetch or axios, I get a CORS error:
Access to XMLHttpRequest at 'https://MY_SEARCH_SERVICE.search.windows.net/indexes/users/docs?api-version=2021-04-30-Preview&%24top=5&search=matt*&%24searchFields=name&%24select=id%2Cname%2Cemail&api-key=MY_API_KEY' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
However, if I put the same GET URL into a browser, it returns the list of expected results with no errors.
Here's my code (to run, create a Svelte app and put this in App.svelte or use the Svelte REPL. You must also have an Azure Search service set up, and you'll need to replace the placeholder variables MY_SEARCH_SERVICE and MY_API_KEY with your own, along with an index on which you want to try this):
<script lang="ts">
import { onMount } from "svelte";
const service = "https://MY_SEARCH_SERVICE.search.windows.net";
const index = "users";
const endpoint = `${service}/indexes/${index}/docs`;
const params = new URLSearchParams({
"api-version": "2021-04-30-Preview",
"api-key": "MY_API_KEY",
"$top": "5",
"$searchFields": "name,email",
"$select": "id,name,email"
});
const headers = new Headers({
"accept": "application/json"
});
onMount(async () => {
console.log(`${endpoint}?${params}`);
const response = await fetch(`${endpoint}?${params}`, {
headers: headers
});
console.log(await response.json());
});
</script>
I am creating a Firefox extension which posts some data to a database.
I made all parts in a modular fashion and am now combining everything piece by piece.
As such I know that my code to POST data to the database works.
Now here is the part that stumps me :
When I then add this code to my firefox extension
I get the following error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3003/timed_shot_create. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 400.
Now ofcourse CORS was nothing new and to be expected when dealing with Cross Origin Resource Sharing, it is even in the name.
But the reason why I am here is because this pertains only to the response of the POST request. The request itself is fine and allowed with the following piece of config in the server:
app.use(
cors({
//todo change to proper origin when live
origin: "moz-extension://d07f1e99-96a0-4934-8ff4-1ce222c06d0d",
method: ["GET", "POST"],
})
);
Which was later changed to:
app.use(
cors({
origin: "*",
method: ["GET", "POST"],
})
);
And then simplified even more to:
app.use(cors())
This is in Nodejs btw using cors middleware.
But none of this seems to work when it is used inside a firefox extension, as a local client page works as intended but as soon as I add this to a firefox extension I get a CORS error specifically pertaining to the reponse message.
The client side post (in the background script of the extension) is:
async function postTimedShot(post_options) {
const response = await fetch(post_endpoint, post_options);
//console.log(response);
const json_response = await response.json();
console.log(json_response);
}
let post_options = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(response_data),
};
postTimedShot(post_options);
And the api looks like this:
app.post("/timed_shot_create", (req, res) => {
console.log("Received POST request");
const data = req.body;
console.log(data);
const timeStamp = data.time_stamp;
//TODO add screenshot and Description text maybe??
//const lastName = data.last_name
const queryString =
"INSERT INTO " + timed_shots_database + " (time_stamp) VALUES (?)";
getConnection().query(queryString, [timeStamp], (err, results, fields) => {
if (err) {
console.log("Failed to insert new user: " + err);
res.sendStatus(500);
return;
}
//Todo change this message when adding more data in body
//res.header("Access-Control-Allow-Origin", "moz-extension://d07f1e99-96a0-4934-8ff4-1ce222c06d0d");
res.json({
status: "Success!!!",
time_stamp: timeStamp,
});
console.log("Inserted a new user with id: ", results.insertId);
});
});
Furthermore, this extension is only for personal use and will work with a local server under my complete control so complications due to security or cloud usage that people want to mention are appreciated but not necessary (I think, I am a bit of novice).
I will be happy to clarify anything that is unclear, or change this post if necessary, but I think it is a unique question as far as I could see on SO. Additionally if I need to provide more of the codebase I will.
I will also update this post if I find out more about this problem.
Thank you for reading :3.
After reading about this post https://stackoverflow.com/a/53025865/5055963
on SO I found out that it had to do with the permissions in the manifest of the extension.
Adding this line: "://.localhost/*".
Solved the issue for me.
I'm using ngrok to expose my local webserver to the internet. In the terminal window for ngrok, you can see a list of the HTTP requests.
I'm using axios for HTTP requests in my react native app.
I'm implementing a live search component, and I want to cancel previous request so the final results don't get messed up. I'm implemented the canceltoken in my requests. This is my code so far (simplified):
const cancelToken = axios.CancelToken;
let source;
const liveSearch = async (searchQuery) => {
try {
if (source) {
source.cancel();
}
source = cancelToken.source();
const response = await axios({
method: 'get',
url: `http://x.ngrok.io/search/${searchQuery}`,
cancelToken: source.token
});
return response.data
} catch (err) {
if (axios.isCancel(err) {
console.log(`cancelled request: ${searchQuery}`);
}
}
};
As you can see, if first check if a source exists. If so, cancel it, and create a new source. Then I do the request with the cancelToken as an object property.
When I run my app and check the console output of my app, I see 'cancelled request' correctly. But, in ngrok, I still see the HTTP requests for the 'cancelled' requests. An example:
In console output app (searching for 'hello'):
- cancelled h
- cancelled he
- cancelled hel
- cancelled hell
In ngrok terminal window:
- GET /search/hello 304 Not Modified
- GET /search/hell 304 Not Modified
- GET /search/hel 304 Not Modified
- GET /search/he 304 Not Modified
- GET /search/h 304 Not Modified
Is there something wrong with my implementation of the axios canceltoken? Or is it 'normal' that ngrok logs all requests, even the cancelled ones?
I'm using custom tokens and firebase auth. I'm successfully logging in users with email & password and storing the accessToken and refresh tokens. When I go to use the refresh token to get a new access token I'm getting a 401 error. When I try the same post link I'm using in a chrome extension based plugin (for testing REST API's) - the request is successful and I get the desired response. Though with my code in expo & react native I get just a plain, unhelpful 401 error.
My code is as follows:
const headers = {
'Authorization': `Bearer ${accessToken}`
}
const data ={
grant_type : "refresh_token",
refresh_token : refreshToken
}
await axios.post(urlTest, data, {
headers: headers
})
.then((response) => {
console.log("Success! ", response)
})
.catch((error : Error) => {
console.error(error.name, error.message);
})
Not sure what I'm doing wrong here. Maybe a cors issue? A fresh pair of eyes would be welcome.
Thanks!
Seems it might have been a CORS issue. Changed where I was hosting the code to handle posting and getting new access token. Works a treat now.
I have an Express 4 application that makes user of csurf for CSRF protection on API routes. The application is working perfectly and CSRF protection is indeed working where requests without the csrf-token header will give the appropriate error.
I make use of Ava for testing with supertest for testing routes. The following test fails when CSRF checking is enabled but passes if I remove the middleware:
test('booking api no auth', async t => {
t.plan(4)
const server = await request(makeServer(t.context.config, t.context.connection))
const csrf = await server
.get('/')
.then(res => new JSDOM(res.text))
.then(dom => dom.window.document.querySelector('meta[name="csrf_token"]'))
.then(csrfMeta => csrfMeta.getAttribute('content'))
const GET = await server
.get('/v2/Booking')
.set('csrf-token', csrf)
const POST = await server
.post('/v2/Booking')
.set('csrf-token', csrf)
.send({
name: 'Test',
description: 'Test',
category: 'diving',
minimumPax: 1,
maximumPax: 2,
priceAdult: 1,
priceChild: 1
})
const res = { GET, POST }
t.is(res.GET.status, 403)
t.deepEqual(res.GET.body, text['403'])
t.is(res.POST.status, 201)
t.truthy(res.POST.body._id)
})
I have verified that the header is indeed set in the request. Any ideas or suggestions for alternative libraries that works is appreciated.
I've previously also had errors with supertest and logging in, still unresolved, but using supertest-session seems to have fixed this for me. Fix was to replace:
import request from 'supertest'
with
import request from 'supertest-session'
and everything magically works.