Axios request to Gmail API unauthorised error? - javascript

I have tried to send, with Google API and Axios, a new email:
async SendMail (req, res) {
try {
const email = `From: ${req.body.sender}\r\n` + `To: ${req.body.receiver}\r\n` + `Subject: ${req.body.subject}\r\n\r\n` + req.body.message
const response = await axios.post(`https://www.googleapis.com/upload/gmail/v1/users/${req.body.userId}/messages/send`, email, {headers: {Authorization: `Bearer ${req.body.token}`, 'content-type': 'message/rfc822'}})
res.status(200).send({data: response.data, status: 'ok'})
} catch(err) {
console.log('error => ', err)
res.status(404).send({
error: 'Error for the recuperation of Google info'
})
}
}
It tells me I am unauthorised but I have added the correct scopes.
error: {
response: {
status: 401,
statusText: 'Forbidden',
...
}
}
The accessToken is working I have done a call with a get with it and it worked pretty fine.
This is my scope: https://mail.google.com/

Related

How can i fix CORS error firebase function

I currently have a CORS problem that I can't solve, here is my code:
gogologo.js
const souscription = async (req, res) => {
if (!req.body.data || !req.body.data.souscrireParams) {
console.error('souscription input error')
res.json({ data: { error: 'souscription input error' } })
return
}
const souscrireParams = req.body.data.souscrireParams
console.log('souscription:', JSON.stringify(req.body.data.souscrireParams))
var data = JSON.stringify(souscrireParams)
const headers = {
'x-api-key': apiKey,
'Content-Type': 'application/json'
}
var reqConfig = {
method: 'post',
url: 'url',
headers: headers,
data: data
};
console.log("reqConfig = ", reqConfig)
try {
const response = await axios(reqConfig)
const result = response.data
if (result.resultat === 'success') {
res.json({ data: result })
} else {
const msg = {
to: 'mail',
from: 'mail',
subject: 'souscription Fail',
html: `deal <br><br> ${JSON.stringify(souscrireParams)}<br><br>Error:<br><br>`,
}
sgMail.setApiKey(sgKey)
await sgMail.send(msg)
res.json({ data: { error: { message: 'souscrire error' } } })
}
} catch (error) {
console.log('error message : ', error.message)
console.log('error : ', error)
const msg = {
to: 'mail',
from: 'mail',
subject: 'souscription fail',
html: `deal <br><br> ${JSON.stringify(souscrireParams)}<br><br>Error:<br><br>${JSON.stringify({ error: error.message })}`,
}
sgMail.setApiKey(sgKey)
await sgMail.send(msg)
res.json({ data: { error: error.message } })
}
}
exports.souscription = souscription
index.js
exports.souscription = functions.runWith({
vpcConnector: 'app-functions-connector',
vpcConnectorEgressSettings: 'ALL_TRAFFIC'
}).https.onRequest(async (req, res) => {
console.log('souscription IP:', await publicIp.v4())
cors(req, res, async () => {
gogologo.souscription(req, res)
})
})
when I press the subscribe button, it displays an error message "Access to fetch at 'url genereted by firebase function' from origin 'url app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."
with a post error.

CORS response when sending a DELETE request

I am trying to send a DELETE request to my backend server, but I keep getting this response printed to my console:
Response {type: 'cors', url: 'http://localhost:3003/delete', redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:3003/delete"
[[Prototype]]: Response
I don't know why this is happening.
server.js
const express = require('express')
const knex = require('knex')
const cors = require('cors')
const db = knex({
client: 'pg',
connection: {
host: '127.0.0.1',
user: 'postgres',
password: 'psql',
database: 'blogspot',
port: 5432
}
});
const app = express();
app.use(express.json())
app.use(cors())
// Delete Blog
app.delete('/delete', (req, res) => {
const {id} = req.body;
db.select('*').from('blogs')
.where({
id: id
})
.del()
.then(() => {
res.json('Deleted Successfully')
})
.catch(err => res.status(404).json('An error occured'))
})
fetchAPI.js
function deleteBlog (blog) {
fetch('http://localhost:3003/delete', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(blog)
}).then(resp => {
console.log(resp)
if (resp === 'Deleted Successfully') {
navigate(0)
} else if (resp === 'An error occured') {
console.log('Something went wrong')
} else {
console.log('ERROR')
}
})
}
I keep getting 'ERROR' printed to my console along with the cors response I pasted above. When I refresh, I find that the blog has been deleted, but the response was definitely an error since navigate(0) wasn't run and ERROR was printed to my console. I have tried removing the 'Content-Type': 'application/json' header and sending the id as request params instead but I got the same error.
The fact that the response is of type "cors" just means that some contents are filtered by CORS policy (see https://developer.mozilla.org/en-US/docs/Web/API/Response/type) but you didn't get any error code, the statusCode is 200.
Since your response content type is JSON, you must also resolve the json parsing before reading the response:
function deleteBlog(blog) {
fetch('http://localhost:3003/delete', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(blog)
})
.then(data => data.json())
.then(resp => {
// I also suppose that you will more likely find
// your "Deleted successfully" in the resp.body property, so :
if (resp.body === 'Deleted Successfully') {
navigate(0)
} else if (resp.body === 'An error occured') {
console.log('Something went wrong')
} else {
console.log('ERROR')
}
})
}

Retrieve access_token from console log using Mocha

I can get the entire response log using console.log(res) but can't retrieve access_token from it. The response containing access_token looks like this:
accept: [Array],
'content-length': [Array]
}
},
text: '{"access_token":"eyJhbGciOiJS....
I've tried the following:
.end( function (res, err, access_token, refresh_token) {
if (err) console.error(err);
else {
console.log(res)
expect(res).to.have.status(200);
//console.log(res.body)
const token = JSON.stringify.access_token;
// token = res.access_token;
console.log(token)
// let accessToken = await auth.getAccessToken();
// console.log(accessToken);
// assert(accessToken != null, 'token is null');
//var token = body.access_token
//console.log(token + "see on token");
// console.log(`options.access_token: ${options.access_token}`);
This is what I'm getting
UPDATE: By using the below code, parsing and using stringify I'm able to log out the token, but I'm still not able to use the parsed in the next request as header, getting undefined
chai.request(uaaUrl)
.post('/oauth/token')
.set('Content-Type', 'application/x-www-form-urlencoded')
.set('Accept', '*/*',)
.send(Authuser)
.end(function(err, res, body) {
const eurotoken = JSON.parse(JSON.stringify(res.body.access_token));
console.log('parsedd token', eurotoken);
expect(res).to.have.status(200)
done();
})
it('./health', (done) => {
let eurotoken;
chai.request(euro_url)
.get('/request-statuses')
.set('Content-Type', 'application/x-www-form-urlencoded')
.set('Accept', '*/*',)
.set('Authorization', `Bearer ${eurotoken}` )
.end( function (res, err, body) {
if (err) console.error(err);
else {
expect(res).to.have.status(200)
done();
}
done();
})
});

Can not download file while sending request from one node.js server to another

I am facing some issue while downloading file using node.js. I have scenario like my angular component is sending the file request. in my first node server I am doing the token validation and then redirecting to another node server where actually the execution happens. I am explaining my code below.
service.ts:
submitAndDownloadFile(formdata : any ){
const token = localStorage.getItem('token')
let headers = new HttpHeaders({
Authorization: 'Basic ' + token
})
const cecID = localStorage.getItem('cec');
const AppUrl = `${environment.nodeJsBaseUrl}:${environment.hostingNodeJsContainerPort}/convert-test-cases/${cecID}`;
return this.httpClient.post(AppUrl, formdata, { responseType: 'blob', observe : 'response', headers : headers});
}
Here I am sending the request to my first node.js server which code has given below.
app.js(first:port-8000):
router.post('/convert-test-cases/:id', middleware.auth, (req, res) => {
try{
let postRequestOptions = {
url: '',
method: 'POST',
json: true,
headers: {},
body: {},
};
postRequestOptions.url = 'http:localhost:9000/convert-test-cases';
postRequestOptions.headers = {
'Content-Type': 'application/json',
};
postRequestOptions.body = req.body;
request(postRequestOptions, async (error, response, pathList) => {
if(error) {
console.log('error', error);
}else{
res.send(pathList);
}
})
}catch(e){
responseObj = {
status: 'error',
msg: 'Error occurred while processing your request',
body: null
}
return res.send(responseObj);
}
})
Here I am doing the token validation using middleware.auth and sending same request to another node.js file which code is explained below.
app.js:(second-port-9000):
router.post('/convert-test-cases', async (req, res) => {
try{
let response = await ctcCtrl.convertTestCase(req.body, req.files);
if(response.status == 'success'){
res.set('Access-Control-Expose-Headers','*, Content-Disposition');
return res.download(response.fileName,response.fileName);
}else{
return res.send(response);
}
}catch(e){
responseObj = {
status: 'error',
msg: 'Error occurred while processing your request',
body: null
}
return res.send(responseObj);
}
})
Here only I am doing some execution and downloading the file. If I am connecting angular to node-9000 its working fine but my requirement is first I have to connect to port-8000 to some token validation and after that I have to send same req.body and re.file to app.js which is running in 9000 using request module. As per my code its not working at all.

Server status 400 blocks json from sending response to client

I'm currently developing client side for my app.
When i try to login user in case where email and password is correct everything works fine but sending error data isn't occuring because status(400) blocks it.
Here is part of my server side code for user login that isn't sending object with isAuth, message, err:
User.findOne({ email: req.body.email }, (err, user) => {
if (!user) return res.status(400).json({
isAuth: false,
message: "Auth failed, bad email",
err
})
But when I make it like that i get the error with all parameters:
User.findOne({ email: req.body.email }, (err, user) => {
if (!user) return res.json({
isAuth: false,
message: "Auth failed, bad email",
err
})
Another strange thing is that when I send bad request with Postman I'm getting all the response data.
And here is client side function that is making request, the console.log(request) part is blocked because of status 400:
const submitForm = async (e) => {
e.preventDefault()
const request = await axios.post('/api/login', { email: email, password: password }).then(res => res.data)
console.log(request)
dispatch({
type: "USER_LOGIN",
payload: request
})
}
And here is some of Chrome stuff from console:
xhr.js:166 POST http://localhost:3000/api/login 400 (Bad Request)
createError.js:17 Uncaught (in promise) Error: Request failed with status code 400
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:60)
There was an axios error/bug.
I have rewrited my code using fetch API. It seems that axios has some kind of bug when it comes to handling 4xx and 5xx status.
Now client part looks like this:
const submitForm = async (e) => {
e.preventDefault()
const request = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ email, password }),
headers: {
'Content-Type': 'application/json',
}
}).then(res => res.json())
console.log(request)
dispatch({
type: "USER_LOGIN",
payload: request
})
}
At the server side everything is just as it should be, return res.status(400).send(data)

Categories

Resources