I am using Axios with the proxy option I want to check bad proxy so I decide to set timeout to my GET request.
here is code:
let res= await axios.get(`http://somedomain.com`,
{
timeout:1500,
proxy: {
host: proxyList[indexOfProxy].host,
port: proxyList[indexOfProxy].port,
auth: {
username: '',
password: ''
},
}
}
).catch(err => {
console.log(`proxy ${indexOfProxy} not working.`);
});
but actually timeout did not work, it spends a long time to go to catch block .
Use axios.create()
const axios = require('axios').default;
const instance = axios.create({
baseURL: 'https://wainot.trade',
timeout: 5000,
});
async function run() {
try {
let res = await instance.get()
} catch (error) {
console.log('no')
}
}
run()
Related
So basically here is the scenario. The user tries to access a protected API link. During the request stage, The Next.js middleware checks if the token is correct, decodes the token and then creates a current user property with response.user and if possible, checks if the exists on the MongoDB database
This is what the middleware.js currently looks like
interface CustomNextResponse extends NextResponse {
request: {
userId: string;
};
}
export async function sign(payload: JwtPayload, secret: string): Promise<string> {
const iat = Math.floor(Date.now() / 1000);
const exp = iat + 60 * 60; // one hour
return new SignJWT({ ...payload })
.setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
.setExpirationTime(exp)
.setIssuedAt(iat)
.setNotBefore(iat)
.sign(new TextEncoder().encode(secret));
}
export async function verify(token: string, secret: string): Promise<JwtPayload> {
const { payload } = await jwtVerify(token, new TextEncoder().encode(secret));
return payload;
}
export async function middleware(request: NextRequest) {
try {
const refreshToken = request.cookies.get('X-Refresh-Token')?.value;
const requestHeaders = new Headers(request.headers);
const bearerToken = requestHeaders.get('Authorization');
if (!refreshToken) {
throw new Error('Unauthorized');
}
if (!bearerToken) {
throw new Error('Unauthorized');
}
const accessToken = bearerToken.split(' ')[1];
if (!accessToken) {
throw new Error('Unauthorized');
}
const decode: JwtPayload = (await verify(accessToken, secretKey)) as JwtPayload;
const response = NextResponse.next() as CustomNextResponse;
response.request = {
userId: decode.id
}
return response;
} catch (error) {
const errorObject = error as Error;
return new NextResponse(JSON.stringify({ success: false, message: errorObject.message }), {
status: 401,
headers: { 'content-type': 'application/json' },
});
}
}
But in the Nextapi at pages/api/me I can neither access the property with req nor res
async function handler(req: CustomNextApiRequest, res: NextApiResponse) {
//req.userId and res.userId give me undefined
Is it case the case then that middleware cant does not store custom properties to be accessed when making a request the same that Express.js does it? plus can you access MongoDB within the middleware?
I'm trying to do a delete request. I can fetch the API route through pages/api/people/[something].js.
And this is the response I got from the browser's console.
DELETE - http://localhost:3000/api/people/6348053cad300ba679e8449c -
500 (Internal Server Error)
6348053cad300ba679e8449c is from the GET request at the start of the app.
In the Next.js docs, for example, the API route pages/api/post/[pid].js has the following code:
export default function handler(req, res) {
const { pid } = req.query
res.end(Post: ${pid})
}
Now, a request to /api/post/abc will respond with the text: Post: abc.
But from my API route pages/api/people/[something].js, something is undefined.
const { something } = req.query
UPDATED POST:
React component
export default function DatabaseTableContent(props) {
const id = props.item._id; // FROM A GET REQUEST
const hide = useWindowSize(639);
const [deletePeople] = useDeletePeopleMutation();
async function deleteHandler() {
await deletePeople(id);
}
return <Somecodes />;
}
apiSlice.js
export const apiSlice = createApi({
// reducerPath: "api",
baseQuery: fetchBaseQuery({ baseUrl: url }),
tagTypes: ["People"],
endpoints: (builder) => ({
getPeople: builder.query({
query: (people_id) => `/api/people/${people_id}`,
providesTags: ["People"],
}),
deletePeople: builder.mutation({
query: (studentInfo) => ({
url: `api/people/people-data/student-info/${studentInfo}`,
method: "DELETE",
headers: {
accept: "application/json",
},
}),
invalidatesTags: ["People"],
}),
}),
});
export const {
useGetPeopleQuery,
useDeletePeopleMutation,
} = apiSlice;
pages/api/people/people-data/student-info/[studentInfo].js
import { ObjectId, MongoClient } from "mongodb";
async function handler(res, req) {
const { studentInfo } = req.query; // the code stops here because "studentInfo" is undefined
const client = await MongoClient.connect(process.env.MONGODB_URI.toString());
const db = client.db("people-info");
if (req.method === "DELETE") {
try {
const deleteData = await db
.collection("student_info")
.deleteOne({ _id: ObjectId(studentInfo) });
const result = await res.json(deleteData);
client.close();
} catch (error) {
return res.status(500).json({ message: error });
}
}
}
export default handler;
The order of params passed to your handler functions needs to be reversed.
For NextJS API routes the req is the first param passed to the handler and the res param is second.
Example handler function from NextJS documentation:
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
import {
createClient,
defaultExchanges,dedupExchange, cacheExchange, fetchExchange,
subscriptionExchange,
gql
} from "#urql/core";
import { createClient as createWSClient } from "graphql-ws";
import { pipe, subscribe } from "wonka";
import { getToken, setToken } from "./helper";
const wsClient = createWSClient({
url: 'wss://**********/subscriptions',
reconnect: true,
});
const client = createClient({
url: "https://***********/",
fetchOptions: () => {
const token = getToken()
return token ? { headers: { authorization: `Bearer "${token}"` } } : {}
},
// the default:
exchanges: [
...defaultExchanges,
subscriptionExchange({
forwardSubscription(operation) {
return {
subscribe: (sink) => {
const dispose = wsClient.subscribe(operation, sink);
return {
unsubscribe: dispose,
};
},
};
},
}),
]
});
SUB_TO_MESSAGES = async () => {
console.log('sub')
const token = getToken();
console.log(String(token))
const { unsubscribe } = pipe(
await client.subscription(messageAdded,{ jwt: token }),
subscribe((result) => {
console.log(result)
})
)
};
I dont get the same issue with try and catch using GraphQL-WS but I still dont get any data from the server. The assignment is a vanillaJS project using GraphQL.I didndt post the url, jwt token,or the GET, POST, REgG as they work as intended. The rendering is done with a proxy. The error message is:
Connection Closed: 4500 Cannot read properties of undefined (reading 'Authorization')
Even playground doesnt work. Something wrong with the endpoint. It worked 2 weeks ago but admin says it still work yet I can find the problem. It used to work for me.
Here is the try and catch version:
import { createClient} from "graphql-ws";
import pStore from "./handler.js";
import { getToken } from "./helper";
const client = createClient({
url: "wss://******/subscriptions",
reconnect: true,
connectionParams:{
headers: {
"Authorization":`Bearer ${getToken()}`
}
},
})
async SUB_MESSAGE() {
try {
console.log('called Gql server')
const onNext = (res) => {
let obj = res.data.messageAdded
console.log(obj)
pStore[obj.id] = obj
pStore.render(obj)
};
let unsubscribe = () => {
/* complete the subscription */
};
new Promise((resolve, reject) => {
client.subscribe({
query: `subscription{messageAdded(jwt:"${getToken()}"){id text fromAgent createdAt updatedAt}}`,
},
{
next: (data)=> onNext(data),
error: reject,
complete: () => resolve(true),
})
})
}catch(error){
console.error('There has been a problem with your ws operation:', error);
}
}
Either way I think its a ad character, scope issue but I dont know where.
I have been trying to make a getItem request in an async Lambda function to dynamo DB, and I am not receiving any response at all. Any troubleshooting or help would be greatly appreciated.
in general, I am trying to make a request to a dynamodb table using the AWS SDK getItem, however, when I run my code there is no response for the await ddb.getItem function
so I am kinda lost as to what could be causing this.
// Load AWS SDK
const AWS = require("aws-sdk");
// Set the region
AWS.config.update({ region: "us-east-1" });
// Create the DyanmoDB service object
const ddb = new AWS.DynamoDB({ apiVersion: "2012-08-10" });
const handler = async (
event,
context,
callback,
test = false,
testObjFunc = {
test: () => {
Error("Testing enabled");
}
}
) => {
const response = {
isBase64Encoded: false,
statusCode: 200,
headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" },
multiValueHeaders: {},
body: JSON.stringify({ responseBody })
};
try {
// Parameters for DynamodDB getItem call
const dbParams = {
TableName: "Table_Name",
Key: {
personID: { S: "value" }
},
ProjectionExpression: "value_to_return"
};
// DynamoDB call to check for item
const results = await ddb.getItem(dbParams).promise();
console.log("success");
console.log(results);
} catch (error) {
response.statusCode = 500;
}
return response;
};
module.exports.handler = handler;
You have put the getitem call in try block, as you are not receiving any response means something is gone wrong in the try block.
I am testing my guard middleware, but altough everything seems to be working fine my expect statement fails.
/// auth.test.js
const request = require('supertest');
const express = require('express');
const app = require('../../app');
const authMiddleware = require('./auth.middleware');
const mockRes = () => {
const res = {};
res.status = jest.fn().mockReturnValue(res);
res.sendStatus = jest.fn().mockReturnValue(res);
res.send = jest.fn().mockReturnValue(res);
return res;
};
describe('Authorization', () => {
const guardedRouter = express.Router();
guardedRouter.get(
'/guardedandauthenticated',
[authMiddleware.authenticate, authMiddleware.authorize('admin')],
(req, res, _next) => {
console.log('seems to be working');
res.status(200);
console.log('res is 200000000');
},
);
let accessToken = '';
beforeAll(async () => {
const res = await request(app).post('/auth/login').send({
username: 'admin',
password: 'admin',
});
expect(res.status).toBe(200);
accessToken = res.body.accessToken;
});
it('should allow access to authorized roles', () => {
const response = mockRes();
// #ts-ignore
guardedRouter.handle(
{
headers: { authorization: `Bearer ${accessToken}` },
url: '/guardedandauthenticated',
method: 'GET',
},
response,
);
// THIS EXPECTATION IS FAILED
expect(response.status).toHaveBeenCalledWith(200);
});
});
/// auth.middleware.js
module.exports.authorize = role => {
return async (req, res, next) => {
if (!req.user) {
return res.status(403).send({
message: 'Unauthorized! No token provided!',
});
}
if (req.user.role === undefined) {
const privileges = await userService.getUserPrivileges(req.user.id);
req.user.role = privileges.map(f => f.privilege_name);
}
const userRoles = req.user.role;
const rolesToCheck = Array.isArray(role) ? role : [role];
if (!rolesToCheck.every(r => userRoles.includes(r))) {
return res.status(403).send({
message: `Unauthorized! Required privileges are: ${userRoles.toString()}`,
});
}
return next();
};
};
/// jest outcome
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: 200
Number of calls: 0
I cleaned up the code, my similar assertions are successfull, and the code seems to be working fine, either the way I setup router is incorrect, or, actually I have no clue. Console messages in the router are on the jest output, so it works fine.
Thanks in Advance,
well it turned out to be a jest issue, you need to tell jest that you are done.
it('should allow access to authorized roles', async done => {
const res = { statusCode: 100 };
res.status = function (code) {
res.statusCode = code;
return res;
};
// #ts-ignore
guardedRouter.handle(
{
headers: { authorization: `Bearer ${accessToken}` },
url: '/guardedandauthenticated',
method: 'GET',
},
res,
);
setTimeout(() => {
done();
expect(res.statusCode).toBe(200);
}, 300);
});
so I added a done callback to test case, and checked value after the handler is done. This still does not look like an ideal solution. The thing is that, handle will call 3 functions, one of them is async, I could not get it to report correct without setting a timer. There should be a solution without the timer, can anyone help with that?