HTTP Request Avoiding SSL [duplicate] - express

I'm using axios to send request to diro to create an user with endpoint /user/create.
However, I keep getting an error like this:
Error response: { Error: certificate has expired
at TLSSocket.onConnectSecure (_tls_wrap.js:1055:34)
at TLSSocket.emit (events.js:198:13)
at TLSSocket.EventEmitter.emit (domain.js:448:20)
at TLSSocket._finishInit (_tls_wrap.js:633:8)
Here is my request:
const DIRO_API_KEY = ******
createUserToDiro = ({
phone,
first_name,
last_name,
birth_date,
mcc_code
}) => {
const mobile = phone;
const firstname = first_name;
const lastname = last_name;
const dob = formatDiroDob(birth_date);
const mcc = mcc_code;
axios.post('https://api.dirolabs.com/user/create'), {
firstname,
lastname,
dob,
mobile,
mcc,
apikey: DIRO_API_KEY
})
.then(rs => console.log('Success response:', rs))
.catch(err => console.log('Error response:',err));
};
What is causing this issue and is there any way to fix it ?

Axios library error clearly mentioned that the certificate has expired.
Please ask diro to renew SSL certificate.
Another way we can skip checking for SSL in Axios npm library as follows
const axios = require('axios');
const https = require('https');
// At request level
const agent = new https.Agent({
rejectUnauthorized: false
});
// Make a request for a user
axios.get('/user/create', { httpsAgent: agent })
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.finally(function () {
// always executed
});
This works.

shorter way, using this environment variable
NODE_TLS_REJECT_UNAUTHORIZED=0

Related

req.body is undefined after installing express-static-gzip

I recently added express-static-gzip to my server and have since noticed that my req.body is undefined in my router.post when submitting a form.
Previously it was working without issue but now I am getting a POST 500 internal server error, a Cannot read property "name" of undefined & a Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 error.
here is my form submission:
const handleSubmit = async (e) => {
e.preventDefault();
setStatus("Sending...");
const { name, email, message } = e.target.elements;
let details = {
name: name.value,
email: email.value,
message: message.value,
};
console.log(typeof JSON.stringify(details))
let response = await fetch("/api/v1/mail", {
method: "POST",
headers: {
"Content-Type": "application/json;charset=utf-8"
},
body: JSON.stringify(details),
});
setStatus("Send Message");
let result = await response.json();
alert(result.status);
};
here is my server setup, the route in question is '/api/v1/mail':
const express = require('express')
const path = require('path')
const router = express.Router();
const cors = require("cors");
var expressStaticGzip = require("express-static-gzip")
const mailRoutes = require('./routes/mail');
const server = express()
server.use('/api/v1/mail', mailRoutes)
server.use(cors())
server.use(express.json())
server.use("/", router)
server.use(expressStaticGzip(path.join(__dirname, 'public'), {
enableBrotli: true
}))
server.use(express.static(path.join(__dirname, 'public')))
and here is my POST request:
router.post("/", (req, res) => {
const name = req.body.name;
const email = req.body.email;
const orderId = req.body.orderId
const message = req.body.message;
const mail = {
from: name,
to: "info#example.com ",
subject: "Contact Form Submission",
html: `<p>Name: ${name}</p>
<p>Email: ${email}</p>
<p>Order ID: ${orderId}
<p>Message: ${message}</p>`,
};
contactEmail.sendMail(mail, (error) => {
if (error) {
res.json({ status: "ERROR" , req});
} else {
res.json({ status: "Message Sent" });
}
});
});
})
If the route you're trying to use req.body.name in is this one:
server.use('/api/v1/mail', mailRoutes)
Then, you have to move this:
server.use(express.json())
to be BEFORE that route definition.
As it is, you're trying to handle the route request before your middleware has read and parsed the JSON. Route handlers and middleware are matched and executed in the order they are registered. So, any middleware that needs to execute for a route handler to function must be registered before the route handler itself is registered.

Modifying graphql query variable using express-gateway

I'm trying to modify a graphql query variable using express-gateway.
The code on the gateway is as below,
const axios = require("axios");
const jsonParser = require("express").json();
const { PassThrough } = require("stream");
module.exports = {
name: 'gql-transform',
schema: {
... // removed for brevity sakes
},
policy: (actionParams) => {
return (req, res, next) => {
req.egContext.requestStream = new PassThrough();
req.pipe(req.egContext.requestStream);
return jsonParser(req, res, () => {
req.body = JSON.stringify({
...req.body,
variables: {
...req.body.variables,
clientID: '1234'
}
});
console.log(req.body); // "clientID": "1234" is logged in the body.variables successfully here
return next();
});
};
}
};
Now, when I hit the request from POSTMAN, the request goes through and returns a 200OK only when I include clientID, otherwise, it throws as error
"message": "Variable "$clientID" of required type "ID!" was not provided."
Any idea what could be going wrong here?
The only way I could get this working was by using node-fetch and then making a fetch request to the graphql-sever from my middleware instead of doing a return next() and following the middleware chain.
My setup is something like the following,
Client (vue.js w/ apollo-client) ---> Gateway (express-gateway) ---> Graphql (apollo-server) ---> Backend REST API (*)
When my client makes a graphql request to my gateway, I've modified my middleware to do the following (as opposed to what's in the question),
const jsonParser = require("express").json();
const fetch = require('node-fetch');
module.exports = {
name: 'gql-transform',
schema: {
... // removed for brevity sakes
},
policy: () => {
return (req, res) => {
jsonParser(req, res, async () => {
try {
const response = await fetch(`${host}/graphql`, {...}) // removed config from fetch for brevity
res.send(response);
} catch (error) {
res.send({ error });
}
});
};
}
};

How to do axios.get when the url is password protected in react native?

I am trying to do axios.get. When I put the url on browser and hit enter browser assk me username and password. But I don't know how to set the password and username in axios header in a get method. The Swagger UI is http://api.myslambook.in/swagger/#
This is my code:
import axios from 'axios';
import base64 from 'react-native-base64'
export function FriendRequests ( ) {
state = {
serverData: [],
};
const tok = 'myusername:mypassword';
const hash = base64.encode(tok);
const Basic = 'Basic ' + hash;
axios.get('http://api.myslambook.in/users', {headers : { 'Authorization' : Basic }})
.then(res => {
const serverData = res.data;
this.setState({ serverData });
})
.catch(err => console.log(err));
}
I am getting this error in console:
Request failed with status code 401.
Can anyone help me? Thanks in advance.
For basic authentication the auth object can be used:
axios.get('http://api.myslambook.in/users', {
auth: {
username: 'janedoe',
password: 's00pers3cret'
}
}).then(res => {
const serverData = res.data;
this.setState({serverData});
}).catch(err => console.log(err));
to fix the Can't find variable: btoa error:
npm i -S base-64
and add the following to index.js:
import {decode, encode} from 'base-64'
if (!global.btoa) {
global.btoa = encode;
}
if (!global.atob) {
global.atob = decode;
}
Checkout the docs: https://github.com/axios/axios#request-config

GraphQL / Apollo - Can't get NetworkError

I'm unable to get any network error with my Apollo Client, only GraphQL errors.
I have the client set up like so:
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`)
);
if (networkError) console.log(`[Network error]: ${networkError}`);
});
const client = new ApolloClient({
link: ApolloLink.from([
errorLink,
new HttpLink({
uri: 'http://localhost:4000/graphql'
}),
]),
});
On the server i'm making a request which i parse like this:
.then(res => {
if (res.ok) {
return { blah: res.json(), count };
}
throw new Error();
})
.catch(error => {
throw new AuthenticationError('Must Authenticate');
});
The AuthenicationError just bubbles up to the Client as a GraphQL Error ([GraphQL error]: Message: Must Authenticate,, i basically just want to be able to get the HTTP Status Code from the server request, on the client.
Thanks
Your client side implementation looks correct.
I guess you are using express with some graphl middleware to handle the requests. The main thing is that you would need to handle the authentication process before the graphql middleware comes in to play.
So the authentication is a graphql mutation which you handle directly. In my case it looked kind of like this:
...
const app = express();
app.use(
"/graphql",
bodyParser.json(),
(request, response, next) => authenticationMiddleware(request) // authentication is handled before graphql
.then(() => next())
.catch(error => next(error)),
graphqlExpress(request => {
return {
schema: executable.schema,
context: {
viewer: request.headers.viewer
},
};
}),
);
...
app.listen(...)
Another possibility would be to add the status code to the error response in the graphql errors.
But that depends on the npm package you are using.
e.g. formatError in apollo-server-graphql
https://www.apollographql.com/docs/apollo-server/api/apollo-server.html#constructor-options-lt-ApolloServer-gt

React-native axios with ColdFusion component

I'm trying to send a get request from react native, using axios, to my coldfusion component.
My coldfusion component:
component displayName="react" {
remote any function ajaxLogin(data) returnformat="JSON"{
data = deserializeJSON(arguments.data);
return serializeJSON(login(data));
}
private any function login(data){
loginQuery = new query();
loginQuery.setDatasource("ds");
loginQuery.setName("loginQuery");
loginQuery.addParam(name="UserEmail", value="#arguments.data.userEmail#", cfsqltype="cf_sql_varchar");
loginQuery.addParam(name="UserPW", value="#arguments.data.userPassword#", cfsqltype="cf_sql_varchar");
result = loginQuery.execute(sql="SELECT * FROM Users Where UserEmail = :UserEmail AND UserPW = :UserPW");
rs = result.getResult();
if(rs.recordCount == 0){
return 0;
} else {
return rs.UserID;
}
}
}
My react-native dispatch action:
export const loginUser = ({ email, password }) => {
// login
return (dispatch) => {
dispatch({ type: 'TEST' });
axios.get('https://myserver.com/components/reactNative/react.cfc?method=ajaxLogin', {
params: {
userEmail: email,
userPassword: password
}
})
.then((response) => {
console.log(response.data);
})
.catch((err) => {
console.log(err);
});
};
};
It is returning an error from the catch:
Error: Request failed with status code 500
I am new with axios and react-native. Am I using axios wrong?
Thanks
Status code 500 is a server-side error so you're likely getting a Coldfusion error, check your ColdFusion logs.
Also as you're calling this as a GETrequest you can just open the URL in a browser tab and see if you get any errors dumped to the page (in a development environment)
https://myserver.com/components/reactNative/react.cfc?method=ajaxLogin&userEmail=email&userPassword=password
If this is production then you should see errors in your error logs (somewhere like /var/www/opt/coldfusion_11/cfusion/logs on linux)