Authenticate UBER API through AngularJS 6 & Node - node.js

I am working on an application, in this application we consume UBER API. I am using NODE as backend and AngularJS 6 as frontend.
Workflow
In NODE part I have access authentication and other UBER API. i have tested through JQuery. It's working perfectly. But when I am trying to access with AngularJS 6. I am getting following error.
SyntaxError: Unexpected token h in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.onLoad (http://localhost:4200/vendor.js:11697:51) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:2743:31) at Object.onInvokeTask (http://localhost:4200/vendor.js:41155:33) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:2742:36) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (http://localhost:4200/polyfills.js:2510:47) at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (http://localhost:4200/polyfills.js:2818:34) at invokeTask (http://localhost:4200/polyfills.js:3862:14) at XMLHttpRequest.globalZoneAwareCallback (http://localhost:4200/polyfills.js:3888:17)
text: "https://login.uber.com/oauth/v2/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Flogin&scope=profile%20history%20places%20request&client_id=XXXXXXXXXXXXXXXXXXXXXXXXX"
__proto__: Object
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure during parsing for http://localhost:1455/api/login"
name: "HttpErrorResponse"
ok: false
status: 200
statusText: "OK"
url: "http://localhost:1455/api/login"
__proto__: HttpResponseBase
Here is my code
NODE
app.get('/api/login', function(request, response) {
response.header('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
response.setHeader('Access-Control-Allow-Credentials', true);
var authURL=uber.getAuthorizeUrl(config.uber.scopes);
response.redirect(authURL);
});
AngularJS 6
data.service.ts
UberAuthenticate(){
return this.http.get('http://localhost:1455/api/login');
}
login.components.ts
export class LoginComponent implements OnInit {
constructor(private dataService: DataService) {
}
ngOnInit() {
this.dataService.UberAuthenticate().subscribe((response)=>{
console.log('response is ', response)
},(error) => {
console.log('error is ', error)
})
}
}
My Node application in running on PORT:1455, AngularJS PORT:4200 and callback url http://localhost:1455/api/callback.
I also set some configuration in proxy.config.json
{
"/api/*": {
"target": "http://localhost:1455",
"secure": false,
"changeOrigin": false,
"pathRewrite": {"^/api" : ""}
}
}
I haven't experience on NODE and AngularJS 6. I don't know where I am doing wrong?

Since the authorize endpoint is returning a plain text link, you need to specify it to angular in your service like this:
UberAuthenticate(){
return this.http.get('http://localhost:1455/api/login', { responseType: 'text' });
}
And in the NodeJS part, you will have to return the authorization url, the redirection has to be made in the frontend side.

Related

Axios - Getting socket hang up error while running it on docker container

I am trying to get results from third party API by using Axios npm. Using nested request, first request is to get the token and another one is to get results.
Below code is working fine in my local machine but not in Docker container.
var config = {
method: 'post',
url: gsecConfig.tokenUrl,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: data
};
axios(config)
.then(function (response) {
if (response.data.access_token) {
const config = {
headers: { Accept: 'application/json', Authorization: `Bearer ${response.data.access_token}` }
};
axios.get(gsecConfig.gsecUrl + gsecid, config)
.then(function (response) {
let supplierData = response.data;
res.status(200).json({
"data": supplierData
});
}).catch(function (error) {
res.json({
"errors": error.message,
"name": error.name
});
});
}
})
.catch(function (tokenError) {
if (tokenError) {
res.json({
"errors": tokenError.message,
"name": tokenError.name
});
}
});
});
Getting error like below
"message": "socket hang up",
"name": "Error",
"stack": "Error: socket hang up\n at createHangUpError (_http_client.js:323:15)\n at Socket.socketOnEnd (_http_client.js:426:23)\n at Socket.emit (events.js:203:15)\n at endReadableNT (_stream_readable.js:1129:12)\n at process._tickCallback (internal/process/next_tick.js:63:19)",
"code": "ECONNRESET"
Thanks in advance!
If your server is not Kubernetes, you can change the publish mode to host (default is ingress), the problem will be solved. check this
You can change it in docker-stack like below:
ports:
- target: 3001
published: 3001
protocol: tcp
mode: host
But if this is Kubernetes with node clusters, you should use the ingress mode, I'm facing this issue and still stuck here. Hope someone can help.

Express or Axios Error: socket hang up code: ECONNRESET

This is the first time i post a question here, sorry if some data is missing.
I'm trying to do some web scraping to get some info of a table.
The page only responds with an index.php and when i use the search form, it makes a POST to index.php?go=le with some formData.
To avoid the CORS problem, im making the post with my own API running in localhost. I'm pointing my frontend to my API and i get the response from localhost.
No problem there.
My problem appears when i try to make a second request to my API. The first GET works fine but after that response it keeps failing.
When i restart the server, it works again but only one time.
Here is my API code. I use nodemon server.js to start my server.
server.js
const express = require("express");
const axios = require("axios");
const scrape = require("scrape-it");
const FormData = require("form-data")
const cors = require("cors")
const app = express();
const PORT = process.env.PORT || 5000;
app.use(cors())
const config = {
headers: {
'Content-type': 'multipart/form-data'
},
}
app.get("/get-projects", async (req,res) => {
const testJSON = await axios.post(baseURL +"/index.php?go=le",formData,config)
.then(res => {
console.log("Post successfull...");
return res
}
)
.catch(err => {
console.log("Server error");
return err
}
);
if(testJSON && testJSON.data){
res.send({status: 200, data: testJSON.data});
}else{
res.status(508).send({status: 508, msg: "Unhandled Server Error", failedResponse: testJSON || "empty"})
}
})
app.listen(PORT,()=>console.log(`App running in port: ${PORT}`))
And in my front-end i only have a button with an event that makes a get to my API (http://localhost:5000)
This is my fetch.js that is included by a script tag. Nothing fancy there.
fetch.js
const btn = document.getElementById("btn-fetch-proyects")
const axios = window.axios
const fetchProjects = async () => {
console.log("Fetching...")
axios.get("http://localhost:5000/get-projects")
.then(res=>
console.log("The server responded with the following data: ",res.data)
)
.catch(err => console.log("Failed with error: ",err)
)
return null
}
btn.addEventListener("click",fetchProjects);
In the console where im running the server, i get Server error with this err object:
{
"message": "socket hang up",
"name": "Error",
"stack": "Error: socket hang up\n at connResetException (internal/errors.js:607:14)\n at Socket.socketOnEnd (_http_client.js:493:23)\n at Socket.emit (events.js:327:22)\n at endReadableNT (internal/streams/readable.js:1327:12)\n at processTicksAndRejections (internal/process/task_queues.js:80:21)",
"config": {
"url": "http://186.153.176.242:8095/index.php?go=le",
"method": "post",
"data": {
"_overheadLength": 1216,
"_valueLength": 3,
"_valuesToMeasure": [],
"writable": false,
"readable": true,
"dataSize": 0,
"maxDataSize": 2097152,
"pauseStreams": true,
"_released": true,
"_streams": [],
"_currentStream": null,
"_insideLoop": false,
"_pendingNext": false,
"_boundary": "--------------------------935763531826714388665103",
"_events": {
"error": [
null,
null
]
},
"_eventsCount": 1
},
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "multipart/form-data",
"User-Agent": "axios/0.21.1"
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1
},
"code": "ECONNRESET"
}
I hope someone has a clue about what's happening. I tried all day and i couldn't solve it.
I tried posting to other sites, and it works fine. I thing the problem is with the form POST.
Thanks for reading!!!
At a first glance I see an error in your front-end code. You are using async on the function but then you do not await but you use .then, try not mixing up styles, either you use async/await or .then .catch.
Check if that helps! :)
Obviously the socket is hanging!
Use node unirest and it closes the data stream.
var unirest = require('unirest');
var req = unirest('POST', 'localhost:3200/store/artifact/metamodel')
.attach('file', '/home/arsene/DB.ecore')
.field('description', 'We are trying to save the metamodel')
.field('project', '6256d72a81c4b80ccfc1768b')
.end(function (res) {
if (res.error) throw new Error(res.error);
console.log(res.raw_body);
});
Hope this helps!

read ECONNRESET error occurs in nextjs geinitialProps when sending get request to api

This error occured in next.js app when i send a get request using axios in getInitialPros of _app.js file.
if (typeof window === "undefined") {
// user = await checkAuth(ctx);
// const token = ctx.req.headers.cookie;
console.log("TOKEN", ctx.req.headers);
if (ctx.req && ctx.req.headers.cookie) {
try {
res = await axiosClient("get", { cookie: ctx.req.headers.cookie }).get(
"/auth/currentuser"
);
user = res.data;
console.log("USER IN SERVER SIDE", user);
ctx.store.dispatch(setAuthenticatedUser(res.data));
} catch (err) {
console.log("ERROR in APP", err);
// console.log("USER FOUND IN APP.JS", res.data);
ctx.store.dispatch(removeAuthenticatedUser());
}
}
} else {
try {
res = await axiosClient("get").get("/auth/currentuser");
user = res.data;
// await checkAuth(ctx);
// await checkAuth(ctx,)
console.log("IN CLIENT", res.data);
} catch (err) {}
}
this error occurred when the page is refreshed but it only occurs on server side, not in client side.
ERROR in APP Error: read ECONNRESET
at TLSWrap.onStreamRead (internal/stream_base_commons.js:205:27) {
errno: 'ECONNRESET',
code: 'ECONNRESET',
syscall: 'read',
config: {
url: '/auth/currentuser',
method: 'get',
headers: {
Accept: 'application/json, text/plain, */*',
cookie: 'token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1ZjNhYTJlMmQxN2YxMzAxYTA0NGUxYTIiLCJpYXQiOjE1OTgyODUyMDMsImV4cCI6MTU5ODI4ODgwM30.qtaW-D9P6tJHzL1uHZs3wlzF39UPVkPTLEieuqaVEJY',
'User-Agent': 'axios/0.19.2'
},
baseURL: 'https://tatkaladda.com/api/',
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
this error only occurred in production app not in development mode.
Node.js is not aware of any baseURL. Your browser is. So on the server side you have to provide the full path, on the client side when using relative links they're relative to the base url, eg https://example.com
By: Tim Neutkens - Co-author of Next.js and MDX
One of the suggested workaround is to use full path in the getInitialProps when using axios. In your case change this:
res = await axiosClient("get").get("/auth/currentuser");
to
res = await axiosClient("get").get("http://localhost:3000/auth/currentuser");
//or use external domian if you not on localhost i.e. https:api.example.com/auth/currentuser
If still this does not work, use axios API and set full path on baseUrl as follow:
// axios call
await axios({
method: 'GET',
url: 'http://abc.herokuapp.com/api/' //or baseURL: 'http://abc.herokuapp.com/api/'
)}
Have time! kindly read this, it might help: https://github.com/vercel/next.js/issues/5009
UPDATE
Also you can try to construct your baseURL from getInitialProps context
async getInitialProps({ req }) {
const protocol = req.headers['x-forwarded-proto'] || 'http'
const baseUrl = req ? `${protocol}://${req.headers.host}` : ''
const res = await fetch(baseUrl + '/api/recent/1')
...
}

Koa 404 when calling from Vue

I am trying to build an app with Koa and Nuxt. this is what I have:
Define service to retrieve from firestore:
const Firestore = require('#google-cloud/firestore');
const getItems = () => {
const db = new Firestore({
projectId: '*******',
keyFilename: "******"
});
db.collection('items').get()
.then((snapshot) => {
return snapshot;
})
}
Define them in routes.js:
const Router = require('#koa/router');
const articleService = require('./services/itemservice');
const router = new Router();
router.get('/getitems', async(ctx, next) => {
ctx.body = articleService.getItems();
});
module.exports = router;
Add routes to retrieve from routes.js:
app.use(router.routes());
app.use(router.allowedMethods());
And finally call it from a component:
let articles = axios.get('/getitems')
.then(response => {
console.log(response);
})//.....
I am receiving this error:
response:
{ status: 404,
statusText: 'Not Found',
headers:
{ 'content-type': 'text/html; charset=us-ascii',
server: 'Microsoft-HTTPAPI/2.0',
date: 'Fri, 25 Oct 2019 16:08:00 GMT',
connection: 'close',
'content-length': '315' },
config:
{ url: '/getarticles',
method: 'get',
headers: [Object],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined },
request:
ClientRequest {
_header:
'GET /getitems HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nUser-Agent: axios/0.19.0\r\nHost: localhost\r\nConnection: close\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
timeout: undefined,
method: 'GET',
path: '/getitems',
_ended: true,
res: [IncomingMessage],
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: [Writable],
[Symbol(isCorked)]: false,
[Symbol(outHeadersKey)]: [Object] },
data:
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">\r\n<HTML><HEAD><TITLE>Not Found</TITLE>\r\n<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>\r\n<BODY><h2>Not Found</h2>\r\n<hr><p>HTTP Error 404. The requested resource is not found.</p>\r\n</BODY></HTML>\r\n' },
isAxiosError: true,
toJSON: [Function] }
Can anyone point me in the right direction?
I've never built an app with Nuxt, but I'll try to help you anyway.
First, I recommend you to read about Promises:
- https://github.com/leonardomso/You-Dont-Know-JS/blob/master/async%20%26%20performance/ch3.md
- https://github.com/leonardomso/You-Dont-Know-JS/blob/master/es6%20%26%20beyond/ch8.md
(those are two chapters of a good JS book series!)
Second, you can try two things in order to find the bug:
- add a .catch block to your thenables, to check if something went wrong;
- add a dummy route that just logs an 'OK', to make sure the routes are be registered and up to respond.
I hope this will help you!
I had this problem with my nuxt / express.js app:
If you would try to type in your browser yourURL/getitems your nuxt app will try to route you to that page instead of just to show u the data.
First thing to do, how to say, you need to define what url your backend should handle.
You go to your nuxt.config.js and add this line of code:
serverMiddleware: ["~/api/index.js"],
That means you have a folder called api and in that folder you have an index.js file and thats your express.js / koa app.
Now in your index.js where your express.js / koa app is you need to add at the end of the line this peace of code:
module.exports = {
path: "/api",
handler: app
};
If everything works fine your URL should have now a prefix api and you should be able to get the data with localhost:PORT/api/getitems
Now nuxt wont try to route you to your url/api because it knows now that this is your backend
If you could provide me your folder structure of your nuxt app i could help you more.
Here is more information about serverMiddleware
https://nuxtjs.org/api/configuration-servermiddleware
EDIT:
somewhere you have a Folder, lets say ist named server or api
in that Folder there should be a index.js file and your routes, model, Controllers etc.
Lets say you have a Folder called server and in that Server you have index.js that should look something like this
const Koa = require('koa');
const app = new Koa();
Import routes from "./routes.js"
app.use(routes)
//here you define now your backend path
module.exports = {
//you can use any path you want
path: "/backend",
handler: app
};
app.listen(3000);
Now you Need to go to your nuxt.config.js file and Point to that index.js File
serverMiddleware: ["~/server/index.js"]
Now you can Access your data with axios:
axios.get("/backend/getitems").then(data => { console.log(data) })
You will Need to add backend to your axios url because thats the path you defined that your Server will handle.

mailgun not sending email returning undefined data

I am trying to implement a simple email confirmation on signup flow using Angular 4, nodejs, mailgun-js and mailgun. The problem is the mailgun send:
mailgun.messages().send(data, function(error, body) {
console.log(body);
});
is timing out with the following error on the front-end:
POST http://localhost:3000/users/sendMail net::ERR_EMPTY_RESPONSE
core.js:1448 ERROR
HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false, …}
error
:
ProgressEvent {isTrusted: true, lengthComputable: false, loaded: 0, total: 0, type: "error", …}
headers
:
HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, headers: Map(0)}
message
:
"Http failure response for (unknown url): 0 Unknown Error"
name
:
"HttpErrorResponse"
ok
:
false
status
:
0
statusText
:
"Unknown Error"
url
:
null
__proto__
:
HttpResponseBase
The back-end show now errors but the return value (body) is undefined and the email is not sent. This is my complete back-end sendMail module:
const api_key = '<key-f40360259dea7c667ca06d4aee956421>';
const DOMAIN = '<sandbox836cdf3cfe9c467b916fe5bb0d73e7e7.mailgun.org>';
const mailgun = require('mailgun-js')({ apiKey: api_key, domain: DOMAIN });
// ---------------- sendMail variables -----
router.post('/sendMail', (req, res, next) => {
console.log("Email message data: " + JSON.stringify(req.body));
const data = {
from: 'xxxxdev#gmail.com',
to: [req.body.email, 'xxxxxxx#gmail.com'],
name: req.body.firstName,
code: req.body.workshopCode,
subject: req.body.workshopTitle,
text: req.body.messageBody
};
mailgun.messages().send(data, function(error, body) {
console.log(body);
});
});
Both From and To email are valid email address and the req.body displayed in the console.log is the correct data passed from the Front-End.
This the Front-end sendmail module:
sendEmailConfirmation(message) {
const headers = new HttpHeaders();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
this.http.post('http://localhost:3000/users/sendMail', message).subscribe((data) => {
console.log('Mail return data: ' + data); >>>THIS LINE IS NEVER EXECUTED<<<<<<
},
);
}
What am I missing here??.....
I noticed the absence of a res.send so I added the following:
if (error) throw error;
else {
res.send('Email sent');
}
Now I get a forbidden error on the back-end:
(node:10780) UnhandledPromiseRejectionWarning: Error: Forbidden
at IncomingMessage.res.on (C:\connect2Server\node_modules\mailgun-js\lib\request.js:301:17)
at IncomingMessage.emit (events.js:165:20)
at endReadableNT (_stream_readable.js:1101:12)
at process._tickCallback (internal/process/next_tick.js:152:19)
(node:10780) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a ca
tch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
Please make sure that if you are sending from Europe to also include the host like this:
const mg = mailgun({apiKey: MAILGUN_PRIVATE_API_KEY, domain: MAILGUN_DOMAIN_NAME, host:MAILGUN_HOST});
For Europe, host is api.eu.mailgun.net and for America it's api.mailgun.net from what I know.
Problem solved.....caused by typo in mailgun credentials. The '<' '>' brackets where copied over .....the clue was the Forbidden error.

Resources