Problems integrating into existing server running Express/Sequelize

Ok I manage to understand it a bit more, so it seems it comes from your forest admin backend configuration. We first need to get rid of your log error. Let me investigate and I will come back to you.

And could you please tell me if you’ve made any change on your app.js file?

Sorry i wasn’t able to post for 4 hours. Sure, here’s my app.js file:

It looks like an old app.js file if I’m not mistaken did you try something like generate a new project and copy / paste your old project’s file into the new one? If it is it should explain why it is not working for now. :slight_smile:

I’ve just generated a new project on the same forest-express-sequelize as you have and mine looks like this. Can you try with this one?

const express = require('express');
const requireAll = require('require-all');
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const cors = require('cors');
const jwt = require('express-jwt');
const morgan = require('morgan');
const {
  errorHandler,
  ensureAuthenticated,
  PUBLIC_ROUTES,
} = require('forest-express-sequelize');

const app = express();

let allowedOrigins = [/\.forestadmin\.com$/, /localhost:\d{4}$/];

if (process.env.CORS_ORIGINS) {
  allowedOrigins = allowedOrigins.concat(process.env.CORS_ORIGINS.split(','));
}

const corsConfig = {
  origin: allowedOrigins,
  maxAge: 86400, // NOTICE: 1 day
  credentials: true,
};

app.use(morgan('tiny'));
app.use('/forest/authentication', cors({
  ...corsConfig,
  // The null origin is sent by browsers for redirected AJAX calls
  // we need to support this in authentication routes because OIDC
  // redirects to the callback route
  origin: corsConfig.origin.concat('null')
}));
app.use(cors(corsConfig));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use(jwt({
  secret: process.env.FOREST_AUTH_SECRET,
  credentialsRequired: false,
}));

app.use('/forest', (request, response, next) => {
  if (PUBLIC_ROUTES.includes(request.url)) {
    return next();
  }
  return ensureAuthenticated(request, response, next);
});

requireAll({
  dirname: path.join(__dirname, 'routes'),
  recursive: true,
  resolve: (Module) => app.use('/forest', Module),
});

requireAll({
  dirname: path.join(__dirname, 'middlewares'),
  recursive: true,
  resolve: (Module) => Module(app),
});

app.use(errorHandler());

module.exports = app;

I tried it with all of your app.js as a whole, but now it seems to return a 502 Bad Gateway :

Can you share me the logs of your forest admin server?

@anon16419211
Which logs do you mean exactly? The ones from app.forestadmin.com, or the ones on our server side? The ones on our server side don’t really show much, and those above are from app.forestadmin.com.

@Wolfie the logs from your server that leads to this 502 error might be helpful here, thanks :slight_smile:

@anon37102731

This is all i can see related to forest authentication in the nginx logs:

This is my current app.js after being changed as suggested above:

const express = require('express');
const requireAll = require('require-all');
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const cors = require('cors');
require('dotenv').config();
const jwt = require('express-jwt');
// const morgan = require('morgan');
const {
  errorHandler,
  ensureAuthenticated,
  PUBLIC_ROUTES,
} = require('forest-express-sequelize');

const app = express();
const db = require('./models');
db.sequelize.sync();
let allowedOrigins = [/\.forestadmin\.com$/, /localhost:\d{4}$/];

if (process.env.CORS_ORIGINS) {
  allowedOrigins = allowedOrigins.concat(process.env.CORS_ORIGINS.split(','));
}

const corsConfig = {
  origin: allowedOrigins,
  maxAge: 86400, // NOTICE: 1 day
  credentials: true,
};

// app.use(morgan('tiny'));
// app.use('/forest/authentication', cors({
//   ...corsConfig,
//   // The null origin is sent by browsers for redirected AJAX calls
//   // we need to support this in authentication routes because OIDC
//   // redirects to the callback route
//   origin: corsConfig.origin.concat('null'),
// }));


app.use(cors(corsConfig));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(jwt({
  secret: process.env.FOREST_AUTH_SECRET,
  algorithms: ['RS256'],
  credentialsRequired: false,
}));

app.use('/forest', (request, response, next) => {
  console.log('');
  if (PUBLIC_ROUTES.includes(request.url)) {
    return next();
  }
  return ensureAuthenticated(request, response, next);
});

requireAll({
  dirname: path.join(__dirname, 'routes'),
  recursive: true,
  resolve: (Module) => app.use('/forest', Module),
});

// requireAll({
//   dirname: path.join(__dirname, 'middlewares'),
//   recursive: true,
//   resolve: (Module) => Module(app),
// });


// app.listen(() => {
//   console.log('SERVER IS RUNNING ');
//   app.use(async () => {
//     await forest.init({
//       envSecret: process.env.FOREST_ENV_SECRET,
//       authSecret: process.env.FOREST_AUTH_SECRET,
//       objectMapping: db.Sequelize,
//       connections: { default: db.sequelize },
//     });
//   });
// });

app.use(errorHandler());

module.exports = app;

An error 502 sent by nginx means that the server does not respond to the request.

  • Is nginx correctly configure to redirect calls to /forest/authentication to your node app ?
  • Is your node app correctly running ?
  • Is nginx correctly configured to redirect traffic to the same port your node app is listening to?

The agent itself never returns a 502, this error is sent by your reverse proxy to indicate that it could not contact the server.

You can test your setup by displaying this url directly in your browser: https://server2.timespex.com/forest

When your server returns a 204, it means that the agent is correctly getting the call and responding to it.

If I’m calling your url, I get a 502 error even on this URL. It means that it’s not related to the authentication but to your setup (reverse proxy/agent).

@GuillaumeGautreau

Alright i managed to get it to pass cors, and the Preflight request passes, but now it still fails with this:

This is how my app.js is structured now:

require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const useragent = require('express-useragent');
const http = require('http');
const forest = require('forest-express-sequelize');
const jwt = require('express-jwt');
const {
  errorHandler,
  ensureAuthenticated,
  PUBLIC_ROUTES,
} = require('forest-express-sequelize');

const whitelist = ['http://localhost:8081', 'https://app.forestadmin.com'];
const corsOptions = {
  origin: function (origin, callback) {
    if (whitelist.indexOf(origin) !== -1) {
      return callback(null, true);
    } else {
      return callback(new Error('Not allowed by CORS'));
    }
  }, credentials: true,
};

global.__basedir = __dirname;

const app = express();

const db = require('./models');
db.sequelize.sync();

const server = http.createServer(app);
app.use(cors(corsOptions));
app.use(function (req, res, next) {
  console.log('ACCESS HEADERS');
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
  res.setHeader('Access-Control-Allow-Credentials', true);
  next();
});

app.use('^(?!forest/?$).*', cors(corsOptions));

app.use(useragent.express());
app.use(bodyParser.json({ limit: '10mb', extended: true }));
app.use(bodyParser.urlencoded({ limit: '10mb', extended: true }));

server.listen(process.env.PORT || '3001', () => {
  console.log(`Server is running on port: ${process.env.PORT || '3001'}`);
  app.use(async () => await forest.init({
    envSecret: process.env.FOREST_ENV_SECRET,
    authSecret: process.env.FOREST_AUTH_SECRET,
    objectMapping: db.Sequelize,
    connections: { default: db.sequelize },
  }));
});


app.use(jwt({
  secret: process.env.FOREST_AUTH_SECRET,
  algorithms: ['RS256'],
  credentialsRequired: false,
}));

app.use('/forest', (request, response, next) => {
  if (PUBLIC_ROUTES.includes(request.url)) {
    console.log('PUBLIC ROUTES INCLUDES FOREST');
    return next();
  }
  return ensureAuthenticated(request, response, next);
});

app.use(errorHandler());


module.exports = app;


It does got through the route provided by you guys earlier:
image

image

Hi @Wolfie,

Thank you for your patience.

Could you please share with us the error you get when the /authentication request fails? You can find it in the Preview tab

Thank you

@anon90145840

The response data fails to load there :

Do you have any errors in the console?

@olesyak Yes, though they are the same one that were there from the very beginning of the setup:

Also, am I supposed to handle what /forest/authentication route returns, or does forest-expess-sequelize take care of this on it’s own?

No you are not, forest will do it for you.

Can you please check that you do have this part in your app.js?

let allowedOrigins = [/\.forestadmin\.com$/, /localhost:\d{4}$/];

if (process.env.CORS_ORIGINS) {
  allowedOrigins = allowedOrigins.concat(process.env.CORS_ORIGINS.split(','));
}

const corsConfig = {
  origin: allowedOrigins,
  allowedHeaders: ['Authorization', 'X-Requested-With', 'Content-Type'],
  maxAge: 86400, // NOTICE: 1 day
  credentials: true,
};
app.use('/forest/authentication', cors({
  ...corsConfig,
  // The null origin is sent by browsers for redirected AJAX calls
  // we need to support this in authentication routes because OIDC
  // redirects to the callback route
  origin: corsConfig.origin.concat('null')
}));
app.use(cors(corsConfig));
<...>

@anon90145840

I copied and pasted in exactly the code you sent over to replace the one i had for CORS configuration, but the same problem still persists unfortunately. Should there be something generated to handle the routes then? Like in the /forest foler or maybe in /routes/ ?

I think you can put back the configuration you made.

When I try to access https://server2.timespex.com/forest I get a 403 error from your nginx.

This is probably the source of the issue. You should see “Your application is running” page.

Can you please check it?

@olesyak
Our nginx enforces https, maybe that might be the problem? Our requests are going through to https://server2.timespex.com/forest with a 504 timeout. Can it possibly be that our provider has blocked your ip/domain?

EDIT: We fixed some nginx things, could you try again pinging to our side ? Now it’s an empty response error:

It seems that now this part of your code generates the error we see on /forest

Maybe you can try to refactor it to

const corsOptions = {
  origin: whitelist,
  credentials: true,
};

as you’re using a static array of the allowed origins or check this documentation if you want to keep the function