Self signed certificate error when fetching API locally - javascript

I have a simple .NET Core WebAPI with no authentication. I added Cors with default policy. I have no problem connecting and fetching data from my React website or Postman (everything runs locally on my machine). Now I'm trying to fetch data from that API in super simple node application and I'm getting this error:
file:///Users/aw/Projects/TestNodeApp/node_modules/node-fetch/src/index.js:94
reject(new FetchError(`request to ${request.url} failed, reason: ${error.message}`, 'system', error));
^
FetchError: request to https://localhost:5001/api/teams failed, reason: self signed certificate
at ClientRequest.<anonymous> (file:///Users/aw/Projects/TestNodeApp/node_modules/node-fetch/src/index.js:94:11)
at ClientRequest.emit (node:events:394:28)
at TLSSocket.socketErrorListener (node:_http_client:447:9)
at TLSSocket.emit (node:events:394:28)
at emitErrorNT (node:internal/streams/destroy:157:8)
at emitErrorCloseNT (node:internal/streams/destroy:122:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
type: 'system',
errno: 'DEPTH_ZERO_SELF_SIGNED_CERT',
code: 'DEPTH_ZERO_SELF_SIGNED_CERT',
erroredSysCall: undefined
}
This is my whole node application:
import fetch from 'node-fetch';
async function fetchTeams() {
const response = await fetch('https://localhost:5001/api/teams', { method: 'GET' });
const data = await response.json();
return data;
}
(async () => {
console.log('Process started');
const teams = await fetchTeams();
console.log(teams);
})().finally(() => {
console.log('Process finished');
});
What does it mean? What Am I missing?
Btw. It works fine, when I'm fetching Github API, like this:
async function fetchGithub() {
const response = await fetch('https://api.github.com/users/Microsoft');
const data = await response.json();
return data;
}
So I assume, something is missing in the API. Something that my React website doesn't need, that node app needs.
Thanks for help!

You can use this command to set the NODE_TLS_REJECT_UNAUTHORIZED environment variable:
export NODE_TLS_REJECT_UNAUTHORIZED=0

Try trusting the self signed certificate with dotnet dev-certs
dotnet dev-certs https --trust
For more details please visit this documentation page.

Related

Sending request to webserver using axios

I want to send an array of strings over localhost 3000 with route start then send back a response with status 200 and eventually a map attached to response.body Currently i have this
Client code:
const axios = require('axios');
let listOfNames = ['mikey'];
axios.post(''http://localhost:3000/start'', {
data: { names: listOfNames }
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Server code:
const express = require('express');
const app = express()
const port = 3000
var listOfNames = [];
app.post('/start', async (req, res) => {
listOfNames = req.params.listOfNames;
res.status(200).send("Names added");
});
app.listen(port, () => {
console.log('request recieved');
});
I get this error presemably from how the request is being sent, any help?
TypeError [ERR_INVALID_URL]: Invalid URL
at new NodeError (node:internal/errors:393:5)
at URL.onParseError (node:internal/url:565:9)
at new URL (node:internal/url:645:5)
at dispatchHttpRequest (C:\Users\cmb\rectangleHealth\node_modules\axios\dist\node\axios.cjs:23
94:20)
at new Promise (<anonymous>)
at http (C:\Users\cmb\rectangleHealth\node_modules\axios\dist\node\axios.cjs:2330:10)
at Axios.dispatchRequest (C:\Users\cmb\rectangleHealth\node_modules\axios\dist\node\axios.cjs:
3260:10)
at Axios.request (C:\Users\cmb\rectangleHealth\node_modules\axios\dist\node\axios.cjs:3610:33)
at Axios.httpMethod [as post] (C:\Users\cmb\rectangleHealth\node_modules\axios\dist\node\axios
.cjs:3649:19)
at Function.wrap [as post] (C:\Users\cmb\rectangleHealth\node_modules\axios\dist\node\axios.cj
s:27:15) {
input: '/start',
code: 'ERR_INVALID_URL'
}
Edit: New error ECONNRESET error emerging from applied fixes
AxiosError: read ECONNRESET
at AxiosError.from (C:\Users\cmb\rectangleHealth\node_modules\axios\dist\node\axios.cjs:789:14
)
at RedirectableRequest.handleRequestError (C:\Users\cmb\rectangleHealth\node_modules\axios\dis
t\node\axios.cjs:2744:25)
at RedirectableRequest.emit (node:events:513:28)
at eventHandlers.<computed> (C:\Users\cmb\rectangleHealth\node_modules\follow-redirects\index.
js:14:24)
at ClientRequest.emit (node:events:513:28)
at Socket.socketErrorListener (node:_http_client:494:9)
at Socket.emit (node:events:513:28)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
syscall: 'read',
code: 'ECONNRESET',
errno: -4077,
The console also outputs a 2 json objects called request and config that cannot fit into this post.
I noticed 2 things errors in your code:
First, check your url is correct, instead of
''http://localhost:3000/start'' (you have multiple single quotes wrapping the url)
try,
"http://localhost:3000/start" or 'http://localhost:3000/start' (wrap it in proper double quotes or single quotes)
Second, You are passing the data in your api call as request body and not as request parameters, but you are trying to access it in the parameters of your api.
You should try accessing the request's body on the server side instead of parameters,
app.post('/start', async (req, res) => {
listOfNames = req.body.listOfNames;
res.status(200).send("Names added");
});
Else you might probably face issue while accessing the data in api as well.

How to pass form-data in Loopback code in Mocha Unit Testing NodeJs

I am trying Unit Testing Using Loopback Mocha. I have a POST API /admin/url/createShortUrl which requires actualUrl as a formdata. Also some headers. But headers seems working fine.
I tried multiple answers from stackoverflow but none worked. I am trying to set Content-type as application/json as well as multipart/form-data. But none of it is working.
require('dotenv').config();
import {Client, expect} from '#loopback/testlab';
import {BrickAdminPanelApplication} from '../../application';
import upload from 'multer';
import {setupApplication} from './test-helper';
admin-panel.datasource';
const token =
'eyJ0eXAiOiJKV1QiLCJhbGci';
describe('ShortenedUrlController', () => {
let app: BrickAdminPanelApplication;
let client: Client;
before('setupApplication', async () => {
({app, client} = await setupApplication());
});
after(async () => {
await app.stop();
});
it('invokes POST /admin/url/createShortUrl', async () => {
await client
.post('/admin/url/createShortUrl')
.set({Authorization: `Bearer ${token}`})
.set('emailId', 'myemail#gmail.com')
.set('Content-Type', 'multipart/form-data') //Not working
.set('Content-Type', 'application/json') //Not working
.field('Content-Type', 'multipart/form-data') //Not working
.field(
'actualUrl',
'https%3A%2F%2Fadminss.papers.com%2Fddqwderss1ssdadsdassatsddqposissdcsuy',
)
.expect(400);
});
});
ERROR
1) ShortenedUrlController
invokes POST /admin/url/createShortUrl:
Error: expected 400 "Bad Request", got 415 "Unsupported Media Type"
at Context.<anonymous> (src\__tests__\acceptance\url-shortener.acceptance.ts:92:8)
at processImmediate (node:internal/timers:466:21)
at process.callbackTrampoline (node:internal/async_hooks:130:17)
at Test._assertStatus (node_modules\supertest\lib\test.js:304:12)
at C:\project test\MT-PampersBrick-Admin-API\node_modules\supertest\lib\test.js:80:15
at Test._assertFunction (node_modules\supertest\lib\test.js:338:11)
at Test.assert (node_modules\supertest\lib\test.js:209:21)
at localAssert (node_modules\supertest\lib\test.js:167:12)
at fn (node_modules\supertest\lib\test.js:164:5)
at Test.callback (node_modules\superagent\src\node\index.js:902:3)
at fn (node_modules\superagent\src\node\index.js:1130:18)
at IncomingMessage.<anonymous> (node_modules\superagent\src\node\parsers\json.js:19:7)
at IncomingMessage.emit (node:events:539:35)
at endReadableNT (node:internal/streams/readable:1345:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)

Nextjs API request only works locally

I am trying write to google sheet using 'google-spreadsheet' via Next.js API route. It works perfectly fine when I am testing locally. I can see the data being updated in the google sheet. However, when I deploy it to Vercel, it doesn't work. The 'Functions' log from Vercel shows the following error message.
Error authentication FetchError: request to https://www.googleapis.com/oauth2/v4/token failed, reason: Client network socket disconnected before secure TLS connection was established
at ClientRequest. (/var/task/node_modules/node-fetch/lib/index.js:1461:11)
at ClientRequest.emit (events.js:315:20)
at TLSSocket.socketErrorListener (_http_client.js:469:9)
at TLSSocket.emit (events.js:315:20)
at emitErrorNT (internal/streams/destroy.js:106:8)
at emitErrorCloseNT (internal/streams/destroy.js:74:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
type: 'system',
errno: 'ECONNRESET',
code: 'ECONNRESET',
config: {
method: 'POST',
url: 'https://www.googleapis.com/oauth2/v4/token',
data: {
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: ....
Below is my code if that's any help.
export default async function addRowAPI(req, res) {
if (req.method === 'POST') {
try {
let doc;
try {
doc = new GoogleSpreadsheet(process.env.SPREADSHEET_ID);
} catch (error) {
console.log('error at line 15:', error);
}
try {
await doc.useServiceAccountAuth({
client_email: process.env.GOOGLE_SHEETS_CLIENT_EMAIL,
private_key: (process.env.GOOGLE_SHEETS_PRIVATE_KEY || '').replace(
/\\n/g,
'\n'
),
});
} catch (error) {
console.log('error authentication', error);
}
await doc.loadInfo();
console.log(doc.title);
const sheet = doc.sheetsByTitle['Test_Sheet'];
console.log(sheet.title);
console.log('addRow Doc:', doc);
const newRow = await sheet.addRow(req.body);
res.status(201).send();
} catch (error) {
res.status(500).json(error);
}
} else if (req.method === 'GET') {
res.status(200).json({ ping: 'pong' });
}
}
As mentioned in the comments, the error complains about an authentication issue which indicates wrong/non-existing credentials. Double-check you have all the environment variables properly set in Vercel.

Https request Post from an Angular App to ExpressJS Node.js Server results in request write() end() is not a function and socket hang up Error

I am trying to invoke an Authorization Token API to get an access token.
The trigger is from an angular application via a button click.
The angular service code is below:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { User } from './../auth/user';
import { AuthResponse } from './../auth/auth-response';
import { tap } from 'rxjs/operators';
import { Observable, BehaviorSubject } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class AuthService {
AUTH_SERVER = "http://localhost:3000";
authSubject = new BehaviorSubject(false);
constructor(private httpClient: HttpClient) { }
register(user: User): Observable<AuthResponse> {
return this.httpClient.post<AuthResponse>(`${this.AUTH_SERVER}/register`, user).pipe(
tap((res: AuthResponse ) => {
if (res.token) {
console.log("ACCESS_TOKEN : "+ res.token.access_token);
localStorage.set("ACCESS_TOKEN", res.token.access_token);
localStorage.set("EXPIRES_IN", res.token.token_type);
localStorage.set("ACCESS_TOKEN", res.token.expires_in);
localStorage.set("EXPIRES_IN", res.token.refresh_token);
this.authSubject.next(true);
}
})
);
}
}
And the NodeJS Backend service code is below:
const express = require('express')
const https = require('https')
const app = express()
const router = express.Router();
const cors = require('cors');
const bodyParser = require("body-parser")
const api_helper = require('./util/api_helper')
const port = 3000
app.use(cors());
router.use(bodyParser.urlencoded({ extended: false }));
router.use(bodyParser.json());
router.get('/', (req, res) => {
res.status(200).send('Welcome to Make REST API Calls to Authorisation Server In Express!');
});
router.post('/register', (req, res) => {
console.log('nodejs user name = '+req.body.username);
console.log('nodejs password = '+req.body.password);
var client_id = 'xxxx';
var client_secret = 'yyyyyy';
var auth_header = 'Basic ' + Buffer.from(client_id + ':' + client_secret).toString('base64');
const data = "grant_type=password&username=ddddd&password=eeeeee&client_id=fff&client_secret=Joe75";
const options = {
hostname: 'linux-2222',
port: 8543,
path: '/xxxx/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-formurlencoded',
'Content-Length': data.length
}
};
const requestVar = https.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', (chunk) => {
console.log(`BODY: ${chunk}`);
});
res.on('end', () => {
console.log('No more data in response.');
});
});
requestVar.write(data);
requestVar.end();
req.on('error', (error) => {
console.log('error is ' + error);
});
});
app.use(router);
app.listen(port, () => console.log(`Node server listening on port ${port}!`))
The error I am getting is below:
Entering the server endpoint
nodejs user name = xxx
nodejs password = yyyy
(node:6285) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
**TypeError: req.write is not a function**
at /Users/admin/Development/mod/integrator/src/app/app.js:78:7
at invokeCallback (/Users/admin/Development/mod/integrator/node_modules/raw-body/index.js:224:16)
events.js:288
throw er; // Unhandled 'error' event
^
Error: socket hang up
at connResetException (internal/errors.js:604:14)
at TLSSocket.socketOnEnd (_http_client.js:460:23)
at TLSSocket.emit (events.js:323:22)
at endReadableNT (_stream_readable.js:1204:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
Emitted 'error' event on ClientRequest instance at:
at TLSSocket.socketOnEnd (_http_client.js:460:9)
at TLSSocket.emit (events.js:323:22)
at endReadableNT (_stream_readable.js:1204:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
code: 'ECONNRESET'
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! integrator#0.0.1 start: `NODE_TLS_REJECT_UNAUTHORIZED='0' node ./src/app/contractor_lifecycle_app.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the integrator#0.0.1 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/admin/.npm/_logs/2020-03-28T11_37_38_559Z-debug.log
The nodejs console shows errors with :
TypeError: req.write is not a function and Error: socket hang up.
FYI, I am getting the access token in postname using the relevant http request options. And I was able to use the access token to get a protected resource in postman.
But, I cannot even consume the authorization endpoint via nodejs express.
Please, I need someone to help, any ideas will do.
It appears the problem is with the https.request logic, but I dont know exactly where.
NOTE: The request parameter from the angular app is being successfuly logged in the console in the nodejs https request post function.
The req in the following line:
router.post('/register', (req, res) => {
was overriding the following:
req.write(data);
req.end();
The request write() and end() are methods of the object returned from https.request(options, (res) => {
So, I have updated the code by assigning the https.request(options, (res) => { .. to a new varibale called requestVar.
And now I am getting my acccess token from the authorization server.
I have updated original post with the fix.
Hurray.

Shopify Admin API not working on Google hosted server but works on localhost

My Shopify Admin API not working on Google hosted server but works on localhost. I wonder what am I missing.
I got my order data on localhost but when I upload the code to google server it doesn't work.
I am working on a private app for my shop.
no luck trying to make this works.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const Shopify = require('shopify-api-node');
const shopify = new Shopify({
shopName: 'tinyrabbithole',
apiKey: 'your-api-key',
password: 'your-app-password'
// accessToken: ""
});
shopify.on('callLimits', limits => console.log(limits));
// Take the text parameter passed to this HTTP endpoint and insert it into the
// Realtime Database under the path /messages/:pushId/original
exports.getData = functions.https.onRequest((req, res) => {
shopify.order.list({ limit: 5 })
.then( orders => {
console.log(orders);
return res.status(200).send(orders);
})
.catch( err => {
console.log(err);
return res.status(303).send(err);
})
});
{ RequestError: getaddrinfo ENOTFOUND tinyrabbithole.myshopify.com tinyrabbithole.myshopify.com:443
at ClientRequest.req.once.err (/user_code/node_modules/shopify-api-node/node_modules/got/index.js:182:22)
at ClientRequest.g (events.js:292:16)
at emitOne (events.js:101:20)
at ClientRequest.emit (events.js:188:7)
at TLSSocket.socketErrorListener (_http_client.js:310:9)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at connectErrorNT (net.js:1025:8)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)
name: 'RequestError',
code: 'ENOTFOUND',
host: undefined,
hostname: 'tinyrabbithole.myshopify.com',
method: 'GET',
path: '/admin/orders.json?limit=5',
protocol: 'https:',
url: undefined }
I'll drop this as an answer instead of leaving it in the comments. If you see a getaddrinfo ENOTFOUND error, first make sure you are on the right payment plan. The free tier doesn't allow outgoing API calls.

Categories