Connecting to parse server from https://example.com fails - javascript

I'm trying to connect to the Parse server that is implemented in a VPS, from a website that served with apache.
The website is https://example.com, At first, when I tried to connect to parse server in Javascript codes, I did :
Parse.initialize("myAppId");
Parse.serverURL = 'http://ipOfVPS:1337/parse'
But I get mixed content: the page at '' was loaded over HTTPS .. error.
then I changed parse server Url in javascript to https://ipOfVPS:1337/parse and in the backend of parse server, I run the server with HTTPS. and now when I want to load the website of https://example.com, I get this error in chrome:
net::ERR_CERT_AUTHORITY_INVALID and this error in Firefox:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at.
I will be thankful if anybody helps me with this issue.
Here below I pasted my index.js:
// Example express application adding the parse-server module to expose Parse
// compatible API routes.
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var path = require('path');
var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;
if (!databaseUri) {
console.log('DATABASE_URI not specified, falling back to localhost.');
}
var api = new ParseServer({
databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID || 'XXXX',
masterKey: process.env.MASTER_KEY || 'XXXX', //Add your master key here. Keep it secret!
serverURL: process.env.SERVER_URL || 'https://localhost:1337/parse', // Don't forget to change to https if needed
liveQuery: {
classNames: ["Message","Chats"] // List of classes to support for query subscriptions
},
push: {
android: {
apiKey: 'XXX'
}
}
});
// Client-keys like the javascript key or the .NET key are not necessary with parse-server
// If you wish you require them, you can set them as options in the initialization above:
// javascriptKey, restAPIKey, dotNetKey, clientKey
var options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
requestCert: true,
//ca: fs.readFileSync('/etc/ssl/certs/ca.crt'),
rejectUnauthorized: false
};
var app = express();
// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);
// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
res.status(200).send('I dream of being a website. Please star the parse-server repo on GitHub!');
});
// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function(req, res) {
res.sendFile(path.join(__dirname, '/public/test.html'));
});
var port = process.env.PORT || 1337;
var httpsServer = require('https').createServer(options,app);
httpsServer.listen(port, function() {
console.log('parse-server-example running on port ' + port + '.');
});
// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpsServer);

Related

how to view node js from localhost with https [duplicate]

Given an SSL key and certificate, how does one create an HTTPS service?
The Express API doc spells this out pretty clearly.
Additionally this answer gives the steps to create a self-signed certificate.
I have added some comments and a snippet from the Node.js HTTPS documentation:
var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
// This line is from the Node.js HTTPS documentation.
var options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.cert')
};
// Create a service (the app object is just a callback).
var app = express();
// Create an HTTP service.
http.createServer(app).listen(80);
// Create an HTTPS service identical to the HTTP service.
https.createServer(options, app).listen(443);
For Node 0.3.4 and above all the way up to the current LTS (v16 at the time of this edit), https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener has all the example code you need:
const https = require(`https`);
const fs = require(`fs`);
const options = {
key: fs.readFileSync(`test/fixtures/keys/agent2-key.pem`),
cert: fs.readFileSync(`test/fixtures/keys/agent2-cert.pem`)
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end(`hello world\n`);
}).listen(8000);
Note that if want to use Let's Encrypt's certificates using the certbot tool, the private key is called privkey.pem and the certificate is called fullchain.pem:
const certDir = `/etc/letsencrypt/live`;
const domain = `YourDomainName`;
const options = {
key: fs.readFileSync(`${certDir}/${domain}/privkey.pem`),
cert: fs.readFileSync(`${certDir}/${domain}/fullchain.pem`)
};
Found this question while googling "node https" but the example in the accepted answer is very old - taken from the docs of the current (v0.10) version of node, it should look like this:
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
The above answers are good but with Express and node this will work fine.
Since express create the app for you, I'll skip that here.
var express = require('express')
, fs = require('fs')
, routes = require('./routes');
var privateKey = fs.readFileSync('cert/key.pem').toString();
var certificate = fs.readFileSync('cert/certificate.pem').toString();
// To enable HTTPS
var app = module.exports = express.createServer({key: privateKey, cert: certificate});
The minimal setup for an HTTPS server in Node.js would be something like this :
var https = require('https');
var fs = require('fs');
var httpsOptions = {
key: fs.readFileSync('path/to/server-key.pem'),
cert: fs.readFileSync('path/to/server-crt.pem')
};
var app = function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}
https.createServer(httpsOptions, app).listen(4433);
If you also want to support http requests, you need to make just this small modification :
var http = require('http');
var https = require('https');
var fs = require('fs');
var httpsOptions = {
key: fs.readFileSync('path/to/server-key.pem'),
cert: fs.readFileSync('path/to/server-crt.pem')
};
var app = function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}
http.createServer(app).listen(8888);
https.createServer(httpsOptions, app).listen(4433);
Update
Use Let's Encrypt via Greenlock.js
Original Post
I noticed that none of these answers show that adding a Intermediate Root CA to the chain, here are some zero-config examples to play with to see that:
https://github.com/solderjs/nodejs-ssl-example
http://coolaj86.com/articles/how-to-create-a-csr-for-https-tls-ssl-rsa-pems/
https://github.com/solderjs/nodejs-self-signed-certificate-example
Snippet:
var options = {
// this is the private key only
key: fs.readFileSync(path.join('certs', 'my-server.key.pem'))
// this must be the fullchain (cert + intermediates)
, cert: fs.readFileSync(path.join('certs', 'my-server.crt.pem'))
// this stuff is generally only for peer certificates
//, ca: [ fs.readFileSync(path.join('certs', 'my-root-ca.crt.pem'))]
//, requestCert: false
};
var server = https.createServer(options);
var app = require('./my-express-or-connect-app').create(server);
server.on('request', app);
server.listen(443, function () {
console.log("Listening on " + server.address().address + ":" + server.address().port);
});
var insecureServer = http.createServer();
server.listen(80, function () {
console.log("Listening on " + server.address().address + ":" + server.address().port);
});
This is one of those things that's often easier if you don't try to do it directly through connect or express, but let the native https module handle it and then use that to serve you connect / express app.
Also, if you use server.on('request', app) instead of passing the app when creating the server, it gives you the opportunity to pass the server instance to some initializer function that creates the connect / express app (if you want to do websockets over ssl on the same server, for example).
To enable your app to listen for both http and https on ports 80 and 443 respectively, do the following
Create an express app:
var express = require('express');
var app = express();
The app returned by express() is a JavaScript function. It can be be passed to Node’s HTTP servers as a callback to handle requests. This makes it easy to provide both HTTP and HTTPS versions of your app using the same code base.
You can do so as follows:
var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
var app = express();
var options = {
key: fs.readFileSync('/path/to/key.pem'),
cert: fs.readFileSync('/path/to/cert.pem')
};
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);
For complete detail see the doc
You can use also archive this with the Fastify framework:
const { readFileSync } = require('fs')
const Fastify = require('fastify')
const fastify = Fastify({
https: {
key: readFileSync('./test/asset/server.key'),
cert: readFileSync('./test/asset/server.cert')
},
logger: { level: 'debug' }
})
fastify.listen(8080)
(and run openssl req -nodes -new -x509 -keyout server.key -out server.cert to create the files if you need to write tests)
If you need it only locally for local development, I've created utility exactly for this task - https://github.com/pie6k/easy-https
import { createHttpsDevServer } from 'easy-https';
async function start() {
const server = await createHttpsDevServer(
async (req, res) => {
res.statusCode = 200;
res.write('ok');
res.end();
},
{
domain: 'my-app.dev',
port: 3000,
subdomains: ['test'], // will add support for test.my-app.dev
openBrowser: true,
},
);
}
start();
It:
Will automatically add proper domain entries to /etc/hosts
Will ask you for admin password only if needed on first run / domain change
Will prepare https certificates for given domains
Will trust those certificates on your local machine
Will open the browser on start pointing to your local server https url
Download rar file for openssl set up from here: https://indy.fulgan.com/SSL/openssl-0.9.8r-i386-win32-rev2.zip
Just copy your folder in c drive.
Create openssl.cnf file and download their content from : http://web.mit.edu/crypto/openssl.cnf
openssl.cnf can be put any where but path shoud be correct when we give in command prompt.
Open command propmt and set openssl.cnf path C:\set OPENSSL_CONF=d:/openssl.cnf
5.Run this in cmd : C:\openssl-0.9.8r-i386-win32-rev2>openssl.exe
Then Run OpenSSL> genrsa -des3 -out server.enc.key 1024
Then it will ask for pass phrases : enter 4 to 11 character as your password for certificate
Then run this Openssl>req -new -key server.enc.key -out server.csr
Then it will ask for some details like country code state name etc. fill it freely.
10 . Then Run Openssl > rsa -in server.enc.key -out server.key
Run this OpenSSL> x509 -req -days 365 -in server.csr -signkey server.key -out server.crt then use previous code that are on stack overflow
Thanks

Getting a variable from a Server script to a Client script

Here's the current issue i'm struggling with. I'm on a webapp project, in which I have 2 scripts :
A script called start.js in which I initialize the server and initialize a variable, token. This script is ran when I start the webapp.
A script called viewer.js which initialize a viewer. That viewer requires the previous token to work.
I can't generate the token from the client side, because it requires NodeJS, and as far as I understood NodeJS doesn't work on Client side.
I've tried to use global variables, global methods, or HTTP requests, but none of these methods seems to work so far. Any tip on how to do it ?
Here is what I tried:
// start.js
const ForgeSDK = require('forge-apis');
const express = require('express');
const path = require('path');
var app = express();
app.use('/static', express.static(__dirname + '/static'));
/**
* Token generation
*/
oAuth2TwoLegged.authenticate().then(function(credentials){
setToken(credentials.access_token)
}, function(err){
console.error(err);
});
function setToken(newToken) {
console.log("Definition du nouveau token")
token = newToken;
console.log(token)
};
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.listen(3000, function () {
console.log('Token provider listening on port 3000')
});
// viewer.js
var token = '';
/**
* Viewer initialization
*/
You can pass a callback to your config options to obtain the token (usually via ajax) to requests:
var options = {
env: 'AutodeskProduction',
getAccessToken: function(onGetAccessToken) {
//
// TODO: Replace static access token string below with call to fetch new token from your backend
// Both values are provided by Forge's Authentication (OAuth) API.
//
// Example Forge's Authentication (OAuth) API return value:
// {
// "access_token": "<YOUR_APPLICATION_TOKEN>",
// "token_type": "Bearer",
// "expires_in": 86400
// }
//
var accessToken = '<YOUR_APPLICATION_TOKEN>';
var expireTimeSeconds = 86400;
onGetAccessToken(accessToken, expireTimeSeconds);
}
}
Autodesk.Viewing.Initializer(options, function onInitialized(){
...
See here for details.
And see here and here to create an endpoint to generate access tokens in your Node backend.

Having trouble deploying my node.js app to digital ocean

I am trying to deploy my node.js application to digital ocean. Locally my app works fine when I do:
node server.js
I cloned my repository from gitlab with ssh access and tried doing the same thing, but all the page does is being stuck on the loading stage and eventually it says that my ip address took too long to respond.
ERR_CONNECTION_TIMED_OUT
Eventually I am planning on using something to make it run permanently but I will post a separate post for that.
I normally user my ip address:port number to try view my application.
this is my server.js file:
const express = require('express') ,app = express(), path = require('path'),
socket = require('socket.io'), emailModule = require('./email.js'),
formValidationModule = require('./formValidation.js'), vimeoModule = require('./vimeo.js'),
port = process.env.PORT || 3000;
let
server = app.listen(port,function(){
console.log('listening to requests...');
}),
io = socket(server);
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
io.on('connection', (socket)=>{
console.log('made a connection!');
socket.on('getShortFilmsInfo', ()=>{
vimeoModule.videos.short_films.forEach((y)=>{
vimeoModule.getVideoThumbnail(y).then((data)=>{
socket.emit('shortFilmsInfo', data);
});
})
});
socket.on('getCommercials',()=>{
vimeoModule.videos.commercials.forEach((x)=>{
vimeoModule.getVideoThumbnail(x).then((data)=>{
socket.emit('commercialInfo', data);
})
});
});
socket.on('email', (data)=>{
if(formValidationModule.checkEmptyContact(data.client, data.email, data.name,
data.title, data.message)){
socket.emit('invalidData');
}
else {
/**
* * Here you need to set your email options which includes the clients email, destination email,
* subject and the text (the email content).
*/
emailModule.setMailOptions(data.email,/*'Info#project-gorilla.co.uk'*/'salay777#hotmail.co.uk'
, data.client + ' ' + '(' +
data.name + ')' + ' ' + data.title, data.message).then((mailOpts)=>{
emailModule.send(mailOpts);
});
console.log('email has been sent!');
}
});
});
Port on which you are running node application in digital ocean is blocked from outside access. Configure digital ocean to route any request on port 80 or 443 ( default port for http and https ) to your internal nodejs application.

Connect Nodejs and Angular 2 to SQL Server 2014

I am using Angular 2 and Nodejs to Connect to an SQL Server. If I simply put following code in a js file and run it through the console using node test.js the code deletes the record properly.
Here is the code:
var webconfig = {
user: 'sa',
password: 'test',
server: 'localhost',
database: 'Test',
options: {
encrypt: false // Use this if you're on Windows Azure
}
}
var express = require('express');
var sql = require('mssql');
var http = require('http');
var app = express();
var port = process.env.PORT || 4200;
var connection = new sql.Connection(webconfig, function(err) {
var request = new sql.Request(connection);
request.query('delete from Employee where Id = 2382', function(err, recordset) {
if(err) // ... error checks
console.log('Database connection error');
console.dir("User Data: "+recordset);
});
});
app.listen(port);
console.log(port+' is the magic port');
After that I moved the same file to the src folder in my Angular 2 project (where the index.html file also exists). I put the same code into a function in test.js file like that:
function testConnection()
{
var webconfig = {
user: 'sa',
password: 'test',
server: 'localhost',
database: 'Test',
options: {
encrypt: false // Use this if you're on Windows Azure
}
}
var express = require('express');
var sql = require('mssql');
var http = require('http');
var app = express();
var port = process.env.PORT || 4200;
var connection = new sql.Connection(webconfig, function(err) {
var request = new sql.Request(connection);
request.query('delete from Employee where Id = 2382', function(err, recordset) {
if(err) // ... error checks
console.log('Database connection error');
console.dir("User Data: "+recordset);
});
});
app.listen(port);
console.log(port+' is the magic port');
}
Now I want to call testConnection() from the index page. I have put the <script src="C:\Users\amandeep.singh\Desktop\Angular\my-app\src\test.js"> to script path and call the function using this:
<script>
testConnection();
</script>
The index page executes properly but doesn't show any error nor executes the command. I'm unable to understand why the same code works in the console on Nodejs but not in my index.html.
Help will be appreciated.
You can't run Node applications in the browser. Nodejs is an application that runs Javascript in Google's V8 Javascript VM on your operating system and is meant to be a backend system (at least in the web development stack).
So you basically have to run your Node program on a webserver and make your API requests from the Angular application.
There are several tutorials out there on the internet that help you with this.
Here is the official Angular documentation angular.io

Changin the base URL of loopback lb-services.js

I´m trying to get a client server and a rest api server to connect. I´m using angular js on frontend and loopback on backend.
on the lb-services.js I changed base url to:
var urlBase = 'http://localhost:3000/api';
My angular js is running on port 4000. But when I make a post to the rest api I get this error on my browser:
XMLHttpRequest cannot load http://localhost:3000/api/People. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4000' is therefore not allowed access. The response had HTTP status code 404.
Is there anyway I can proxy the connection or make both servers work together properly?
This is my gulp/server.js:
'use strict';
var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');
var browserSync = require('browser-sync');
var browserSyncSpa = require('browser-sync-spa');
var util = require('util');
var proxyMiddleware = require('http-proxy-middleware');
function browserSyncInit(baseDir, browser) {
browser = browser === undefined ? 'default' : browser;
var routes = null;
if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
routes = {
'/bower_components': 'bower_components'
};
}
var server = {
baseDir: baseDir,
routes: routes
};
/*
* You can add a proxy to your backend by uncommenting the line below.
* You just have to configure a context which will we redirected and the target url.
* Example: $http.get('/users') requests will be automatically proxified.
*
* For more details and option, https://github.com/chimurai/http-proxy-middleware/blob/v0.9.0/README.md
*/
server.middleware = proxyMiddleware('/api', {
target: 'http://localhost:3000/api',
changeOrigin: true
});
browserSync.instance = browserSync.init({
startPath: '/',
server: server,
browser: browser,
port:4000
});
}
browserSync.use(browserSyncSpa({
selector: '[ng-app]'// Only needed for angular apps
}));
gulp.task('serve', ['watch'], function () {
browserSyncInit([path.join(conf.paths.tmp, '/serve'), conf.paths.src]);
});
gulp.task('serve:dist', ['build'], function () {
browserSyncInit(conf.paths.dist);
});
gulp.task('serve:e2e', ['inject'], function () {
browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
});
gulp.task('serve:e2e-dist', ['build'], function () {
browserSyncInit(conf.paths.dist, []);
});
Is there anyway I can proxy the connection or make both servers work
together properly?
It's surprising that you get this error as loopback enables CORS by default. It would be worth checking out the middleware.json file in your loopback server and see whether cors.params.origin is true. Here is the documentation link for your reference.
I'm not sure how you have changed the urlBase for accessing your rest api. I had done it using the angular module config as described here.
You can add CORS support to your LoopBack API:
https://docs.strongloop.com/display/public/LB/Security+considerations#Securityconsiderations-CORS

Categories