Restify and React : how to serve correctly as Express? - deployment

I have developped an app with create react app and i want to deploy it. React is used for the front end and Restify publish API that is consumed by the front end.
The app uses browser history and when i refresh the page Restify return JSON object saying that the route is unknown.
To solve this problem, the Create-react-app documentation explains how to do it well with the Express server :
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
Here is the doc :
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#deployment
Use Case
As mentionned in the create-react-app doc, i use restify to serve static front end React app :
server.get(
/\/(.*)?.*/,
restify.plugins.serveStatic({
directory: "./static",
default: "index.html"
})
);
It's all right with Express but not with Restify. With Express, we must use a middleware first to server static files and next we have to redirect routes to the "index.html" front end app.
With Restify, i have just only used the serveStatic plugin, but it's not enough.
So, if you have an idea to solve that... it would be fabulous !
thx

Related

Unable to do a Nuxt axios post

I have spent some hours trying to figure out my problem without any success.
before reading the explanation
My nuxt site generates dynamic content and works well on client side but for SEO to work and social media shares render dynamic content i need to move my app to SSR. This axios post request do work on client side rendering but does not on SSR and I don't understand the reason and I need help to understand it.
Thanks
For starters I am building a Nuxt app that consumes Drupal as a CMS using a fully decoupled approach and I have been using it for several VUE apps without problem and now I need to do them on Nuxt with a SSR approach because I need heavy SEO on the sites. With Nuxt the same request against oauth/token on drupal doesn't work and I have gone from the complex structure we had to the simple one using both Axios and Nuxt/Axios without any success and alway getting a 400 error code.
I need to run this code first on my app so I can get drupal access token and do some request for data.
Code on store
export const actions = {
async nuxtServerInit({dispatch}, vuexContext, context, app){
await dispatch("setToken");
},
async setToken({ commit, dispatch, getters }, context) {
//prep form data to send
const FormData = require('form-data');
const body = new FormData();
body.append("param1", apiConfig.getValue("param1"));
body.append("param2", apiConfig.getValue("param2"));
body.append("param3", apiConfig.getValue("param3"));
body.append("param4", apiConfig.getValue("param4"));
body.append("param5", apiConfig.getValue("5"));
await this.$axios.$post(url, body)
.then(({data}) => {
//code to process data
commit("SET_TOKEN_DATA", data);
}).catch(error => {
console.log(error)
}).finally(() => {
console.log("FINALY");
});;
}
Some updates
base url is defined on nuxt.config as
// module options for axios
axios: {
baseURL: 'mysite.com'
},
I have tied on http request the following request using both axios and nuxt/axios, I will write short request just to show what I edid
await this.$axios.$post('mysite.com/oauth/token', body)
await this.$axios.$post('/oauth/token', body)
await this.$axios.$post('oauth/token', body)
I have also tried to use
const api = $axios.crate({
baseURL: 'url'
})
api.$axios.post('oauth/token', body)
another updated
Crated a Client Side Nuxt app and the request works.
Fix it, after literally 16 hours trying. When multiform post data you need to send FormData headers on the post and again, this works without any issues using CSR on VUE and Nuxt.
await this.$axios.$post(url, body, { headers: body.getHeaders()}).yada
I don't know if it's Axios or Nuxt the one doing this but I followed a breadcrumb trail to this post https://github.com/axios/axios/issues/318

POST to Salesforce API using Google Tag Manager and JSforce not working?

I want to use Google Tag Manager to send data to our Salesforce org for certain events on our website (user signup, conversion etc). After some research, I realized JSforce would be the easiest way to achieve this. I created a new connected app in Salesforce, tried out the Salesforce API using Postman and successfully managed to create a new user account via the API. Then I moved on to try and achieve the same thing in Google Tag Manager. I read JSforce's docs and attempted to implement everything. But, after multiple hours of troubleshooting and Google searching, I can't seem to make it work.
Here is my current code, which is in a 'tag' in Google Tag Manager that triggers on all pages (just for testing):
https://jsforce.github.io/start/#web-browser
<script src="//cdnjs.cloudflare.com/ajax/libs/jsforce/1.9.1/jsforce.min.js"></script>
<script>
jsforce.browser.init({
clientId: '<MYCLIENTID>',
redirectUri: 'https://cuttersclub.com'
});
https://jsforce.github.io/document/#access-token
var jsforce = require('jsforce');
var conn = new jsforce.Connection({
instanceUrl : 'https://um5.salesforce.com',
accessToken : '<MYACCESSTOKEN>',
});
https://jsforce.github.io/document/#create
conn.sobject("Account").create({ Name : 'My Account #1' }, function(err, ret) {
if (err || !ret.success) { return console.error(err, ret); }
console.log("Created record id : " + ret.id);
});
</script>
I'm getting this error in the browser console:
Uncaught ReferenceError: require is not defined
EDIT: Removing var jsforce = require('jsforce'); solved this problem and accounts are being created in Salesforce. But, now I am getting the following error in the browser console:
Access to XMLHttpRequest at '<URL>' from origin '<CALLBACKURL>' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
As mentioned in the JSforce docs, I think it may be something to do with proxy servers: https://github.com/jsforce/jsforce-ajax-proxy
I don't know that much about salesforce, but "require" is something from node.js, not a function that is implemented in the browser.
If I understand the documentation correctly, then for a browser project it should be enough to call the jsforce script via a script tag. You should not need any way to "require" files after that, since the jsforce script already contains everything you need. So you should be fine if you just remove the offending lines (i.e. all references to "require('jsforce');").

Sending mail from Firebase webapp

var express = require('express');
var app = express();
var nodemailer=require('nodemailer');
var transporter = nodemailer.createTransport('smtps://username#gmail.com:password#smtp.gmail.com');
app.get('/sendMail', function(req,res){
var mailOptions={
to: 'receiver#gmail.com',
subject: 'Test Mail',
html: 'Testing the Mail'
}
transporter.sendMail(mailOptions,function(err,response){
if(err){
res.end('Mail not sent');
}
else{
res.end('Mail sent');
}
});
}).listen(9091);
console.log('This is running');
I am developing a firebase web app. I need to send an email via my web app. I saw some tutorials and found some code. Using the above code I am able to send emails. It runs in the port 9091. The message will be sent when the address bar has www.mywebsite.com/sendMail. But when I host this page to Firebase what changes to be done in this code, whether there must be a change in the port number?. Please help to implement this code in my web app.
Update 2019: Alternatively, you can use the new Trigger Email Firebase Extension (currently in beta).
As I mentioned on my comment, the problem is: your web app was built with NodeJS and you're trying to host it on a static host environment (Firebase Hosting). But Firebase also has Cloud Functions - a service that let's you run functions on a NodeJS environment. So you should deploy your app to that service instead.
It's really easy to Get Started with Cloud Functions. And since you have already set up Firebase hosting, you can simply go to that directory and set up Cloud Functions by using this command:
firebase init functions
A new folder named "functions" will be created and an index.js file will be automatically added to that folder. Now that's the file where you're going to write your functions (we're actually just gonna need 1 function triggered by HTTP to send the email).
So in order to create this function, you would no longer need Express. you can remove that and then change a bit your index.js file to add firebase-functions, so it would become:
//var express = require('express'); No longer needed
//var app = express(); No longer needed
var nodemailer=require('nodemailer');
const functions = require('firebase-functions');
var transporter = nodemailer.createTransport('smtps://username#gmail.com:password#smtp.gmail.com');
exports.sendMail = functions.https.onRequest((req, res) =>{
var mailOptions={
to: 'receiver#gmail.com',
subject: 'Test Mail',
html: 'Testing the Mail'
}
transporter.sendMail(mailOptions,function(err,response){
if(err){
res.end('Mail not sent');
}
else{
res.end('Mail sent');
}
});
});
Now when you want to send a message, you can use this url: https://us-central1-<project-id>.cloudfunctions.net/sendMail
Replace <project-id> with your Firebase Project ID.

IBM Bluemix AppID - how log off / log out?

When using IBM Bluemix App ID, does anyone know how to log out a user? The Node.js server SDK on GitHub sample application and README includes this reference:
const LOGOUT_URL = "/ibm/bluemix/appid/logout";
I have tried various permutations but I haven't been able to find out what URL to use to log out the user (both hostname and extension).
Can anyone help, please?
Many thanks.
According to a posting at https://www.ibm.com/developerworks/library/iot-trs-secure-iot-solutions3/index.html , 'There is no explicit "logout" method at time of writing of this article'.
Having done some digging, killing the session will provide logout functionality. This can be achieved in Node.js with the following:
app.get("/logout", function(req, res){
// Destroy the session
req.session.destroy();
//return the main html file
res.sendfile(__dirname + '/views/index.html');
});
To log out the user, you can use the WebAppStrategy on your logout endpoint like the following:
app.get("/logout", function(req, res, next) {
WebAppStrategy.logout(req);
// If you chose to store your refresh-token, don't forgot to clear it also in logout:
res.clearCookie("refreshToken");
res.redirect("/");
});
Look at the Node SDK readme on WebAppStrategy https://github.com/ibm-cloud-security/appid-serversdk-nodejs.

node.js/everyauth: Maintaining session information with auth request

Ok, so I'm banging my head against the wall trying to figure this out! I'm trying to authenticate via Facebook.
I've got node (0.6.13) running express on an amazon ec2 server. I'm using everyauth for auth, and I have mongodb (mongodb native and connect-mongodb) for persistence. Here is how I instantiate mongo:
var MongoStore = require('connect-mongodb');
var mongo = require('mongodb');
var mongoServer = new mongo.Server('localhost', 27017, {auto_reconnect: true, native_parser: true})
var mongoStore = new MongoStore({
db: new mongo.Db('test', mongoServer, {})
, reapInterval: 3000
});
I'm trying to authenticate through facebook using everyauth. So let's assume my app is running on port 3000, at http://ec2ip:3000/. My facebook app settings have the Website being redirected back to http://ec2ip:3000/.
Express is setup like so:
app.get('/', function (req, res) {
if(!req.session.auth || !req.session.auth.loggedIn)
{
console.log("Not authorized!");
res.redirect('/auth/facebook/');
}
else
{
console.log("Authorized!");
res.sendfile(__dirname + '/www/index.html');
}
});
This was working locally, before I put it on the server. What will happen is that it will correctly authenticate with facebook, and redirect to my website, however req.session.auth will always be undefined, and it will redirect forever. Even though I know it's successfully authenticated, it's just not passing the right session information.
It has something to do with setting up the redirect requests properly so session information is maintained, but I don't understand how it's working under the hood.
Any advice/help would be greatly appreciated. These are the related questions/problems I'm having, but I don't know how to apply it in my case: https://github.com/bnoguchi/everyauth/issues/189 and Node.js & Express session problem
Check what is the value in "req.session". Then go get directly the value in object that you need.