Code Monkey home page Code Monkey logo

express-rest-boilerplate's People

Contributors

3b3ziz avatar danielfsousa avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar donnfelker avatar draysams avatar gkatsanos avatar greenkeeper[bot] avatar irokhes avatar isama92 avatar marcoswcarruda avatar mkutyba avatar mustafa60x avatar rahulkumar66 avatar travislang avatar xantrix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

express-rest-boilerplate's Issues

Register new user with /auth/register doesn't handle duplicate email

Hey Daniel,

In , server/src/controllers/auth.controller.js , it seems to me there's no check to see if the email exists already in the database.. (same check exists in user.controller.js)

/**
 * Returns jwt token if registration was successful
 * @public
 */
exports.register = async (req, res, next) => {
  try {
    const user = await (new User(req.body)).save(); // check here?
    const userTransformed = user.transform();
    const token = generateTokenResponse(user, user.token());
    res.status(httpStatus.CREATED);
    return res.json({ token, user: userTransformed });
  } catch (error) {
    return next(User.checkDuplicateEmail(error));
  }
};

I am running a very similar implementation as your boilerplate and I get
POST http://localhost:3000/auth/register 409 (Conflict) when I try to register with the same email.

I guess what I'd like to understand is the difference between auth.controller and user.controller (are they doing different tasks, are they complementary or are they two different options for authentication?)

Update docker and docker-compose files

MongoDB connection error

Hello folks

I have tried to set up this as per guild but every time I am getting

error: MongoDB connection error: MongooseServerSelectionError: getaddrinfo ENOTFOUND mongodb

Even I tested with another project to check that Mongodb is working fine or not and it is working fine for another project.

this is the configuration I have
MongoDB version: 4.2.1
Mongoose: 5.6.7
node: 12.16.1

this is the mongoose connect method

exports.connect = () => { mongoose .connect(mongo.uri, { useCreateIndex: true, keepAlive: 1, useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false, }) .then(() => console.log('mongoDB connected...')); return mongoose.connection; };

please help me what is the wrong I am doing.

Trying to register with existing email modifies user!

userSchema.pre('save', async function save(next) {
  try {
    if (!this.isModified('password')) return next();

    const rounds = env === 'test' ? 1 : 10;

    const hash = await bcrypt.hash(this.password, rounds);
    this.password = hash;

    return next();
  } catch (error) {
    return next(error);
  }
});

I try to register an existing user email, this shows up:

Mongoose: users.insert({ updatedAt: new Date("Tue, 31 Oct 2017 14:48:55 GMT"), createdAt: new Date("Tue, 31 Oct 2017 14:48:55 GMT"), activationId: '9e85ddc0-be4a-11e7-8af1-ad111a9e7a07', email: '[email protected]', password: '$2a$10$pb5IuAkc65bQF9/6sLEgUuy9VGVKCBYj1ih/nMVi6r9DAKJRyH02a', firstName: 'Takis', lastName: 'Mitsos', _id: ObjectId("59f88d57479844353d5c5b3e"), tokens: [ { token: { expiresIn: 1509547735451, refreshToken: '59f88d57479844353d5c5b3e.5c1abbc11e41ff5b349d460f13cd7068a13914c4ffc312b78e17ad62b44d3719c1ee6ed88c79a5f3', accessToken: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDk1NDc3MzUsImlhdCI6MTUwOTQ2MTMzNSwic3ViIjoiNTlmODhkNTc0Nzk4NDQzNTNkNWM1YjNlIn0.xS-eG50hQKb0o-vt7596xuGvWippSG5J59hmiQOcc44', tokenType: 'Bearer' }, kind: 'jwt' } ], active: false, __v: 0 })``` 

registration and create user

what is the need for registration and before creating the user. what is the use of this thing? can we create a user direct?
Please elaborate on this.

User creation and permissions - Readme?

I'm creating an API for a mobile app and would like to know the logic behind the currently implemented user model.

I'd like to know a little bit more about the intended user registration flow of the boilerplate code.

From my perspective I have two options:

  1. Create an admin user for the mobile app to be able to create users. (Then I'd have to store some credentials on the mobile device, not ideal)
  2. Make the registration endpoint public and allow users to create themselves.

validations need to be wrapper with Joi.object()

As following this boilerplate, I found this error:

TypeError: schema[parameter].validateAsync is not a function

    at validate (/home/techrova/Videos/VideoStream/node_modules/express-validation/lib/index.js:18:55)
    at /home/techrova/Videos/VideoStream/node_modules/express-validation/lib/index.js:26:25
    at Array.map (<anonymous>)
    at /home/techrova/Videos/VideoStream/node_modules/express-validation/lib/index.js:26:8
    at Layer.handle [as handle_request] (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/layer.js:95:5)
    at /home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:335:12)
    at next (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:174:3)
    at router (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:47:12)
    at Layer.handle [as handle_request] (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:317:13)
    at /home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:335:12)
    at next (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:174:3)
    at router (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:47:12)
    at Layer.handle [as handle_request] (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:317:13)
    at /home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:335:12)
    at next (/home/techrova/Videos/VideoStream/node_modules/express/lib/router/index.js:275:10)
    at cors (/home/techrova/Videos/VideoStream/node_modules/cors/lib/index.js:188:7)
    at /home/techrova/Videos/VideoStream/node_modules/cors/lib/index.js:224:17
    at originCallback (/home/techrova/Videos/VideoStream/node_modules/cors/lib/index.js:214:15)

Also here is fix solution

if later this issue still open, I will create a pull request with the fix solution

calling errorHandler instead of next, in router.param userId

The user controller load function calls the errorHandler directly instead of calling next:

https://github.com/danielfsousa/express-rest-es2017-boilerplate/blob/50b2992b620e06b2f3ea6112d3e3032066f9fd03/src/api/controllers/user.controller.js#L6-L18

This function is called by user router:
https://github.com/danielfsousa/express-rest-es2017-boilerplate/blob/50b2992b620e06b2f3ea6112d3e3032066f9fd03/src/api/routes/v1/user.route.js#L17

The express-js example calls next(new Error('failed to load user')) (their example shows how to handle a similar "user-loading" problem...).

v1/docs

I am new rest API what v1/docs suppose to return?

Wait for mongo connection

I realized that the mongoose connect is an async function.

Because that, it's possible that the server start without a established mongo connection. (I could generate errors).

I think in something like that:

exports.connect = async () => {
  await mongoose
    .connect(mongo.uri, {
      useCreateIndex: true,
      keepAlive: 1,
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useFindAndModify: false,
    })
    .then(() => console.log('mongoDB connected...'));
  return mongoose.connection;
};

Or just return mongoose.connect as a promise without then, and await for the resolution of the promise on the other side.

What do you think about that?

mongodb database problem that erases itself

Hello, I have a problem with the template, when I deploy my API on digital ocean my mongo data base erases itself after a while so, that there is no cron job etc, I lose all my collections, I tried with docker and without, same result, if anyone has any idea of ​​the problem

How to use Social login?

I assume you have to do it on client side?

Simple JS example would be nice...

providers: {
    facebook: {
      name: 'facebook',
      url: '/auth/facebook',
      authorizationEndpoint: 'https://www.facebook.com/v2.5/dialog/oauth',
      redirectUri: window.location.origin + '/',
      requiredUrlParams: ['display', 'scope'],
      scope: ['email'],
      scopeDelimiter: ',',
      display: 'popup',
      oauthType: '2.0',
      popupOptions: { width: 580, height: 400 }
    },

    google: {
      name: 'google',
      url: '/auth/google',
      authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
      redirectUri: window.location.origin,
      requiredUrlParams: ['scope'],
      optionalUrlParams: ['display'],
      scope: ['profile', 'email'],
      scopePrefix: 'openid',
      scopeDelimiter: ' ',
      display: 'popup',
      oauthType: '2.0',
      popupOptions: { width: 452, height: 633 }
    }
}
  baseUrl: 'http://localhost:3000', // Your API domain
  
  providers: {
    facebook: {
      clientId: '',
      redirectUri: 'http://localhost:8080/auth/callback' // Your client app URL
    }, 
    google: {
      clientId: '',
      redirectUri: 'http://localhost:8080/auth/callback' // Your client app URL
    }
  }
  methods: {
    authenticate: function (provider) {
      this.$auth.authenticate(provider).then(function () {
        // Execute application logic after successful social authentication
      })
    }
  }
<button @click="authenticate('google')">auth Google</button>
<button @click="authenticate('facebook')">auth Facebook</button>

Explanation for the auth middleware ?

First of all thanks for an amazing repo. It is one of the most useful repos out there for express.

I was going through the structure of it and the only thing I couldn't completely understand was the flow of auth middleware with respect to user roles.

This part basically.
This is the link to the whole file.

  const logIn = Promise.promisify(req.logIn);
  const apiError = new APIError({
    message: error ? error.message : 'Unauthorized',
    status: httpStatus.UNAUTHORIZED,
    stack: error ? error.stack : undefined,
  });

  try {
    if (error || !user) throw error;
    await logIn(user, { session: false });
  } catch (e) {
    return next(apiError);
  }

  if (roles === LOGGED_USER) {
    if (user.role !== 'admin' && req.params.userId !== user._id.toString()) {
      apiError.status = httpStatus.FORBIDDEN;
      apiError.message = 'Forbidden';
      return next(apiError);
    }
  } else if (!roles.includes(user.role)) {
    apiError.status = httpStatus.FORBIDDEN;
    apiError.message = 'Forbidden';
    return next(apiError);
  } else if (err || !user) {
    return next(apiError);
  }

  req.user = user;

not able to create user

after register when i am trying to create user i getting error of "message": "No auth token",
"stack": "Error: No auth token\n
I am using register user access token and put it to header as Athorization

Deploy to heroku get error: heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/"

I try to deploy the default project to https://dashboard.heroku.com/ but I got the error below, can you help me?

2020-03-12T07:20:52.009643+00:00 app[web.1]: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2020-03-12T07:20:52.016589+00:00 app[web.1]: 
2020-03-12T07:20:52.016773+00:00 app[web.1]: npm ERR! A complete log of this run can be found in:
2020-03-12T07:20:52.016893+00:00 app[web.1]: npm ERR!     /app/.npm/_logs/2020-03-12T07_20_52_010Z-debug.log
2020-03-12T07:20:52.092462+00:00 heroku[web.1]: State changed from starting to crashed
2020-03-12T07:20:52.073318+00:00 heroku[web.1]: Process exited with status 1
2020-03-12T07:20:52.913319+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=dev-loc.herokuapp.com request_id=f7bae61b-2240-4546-9213-b30bae7ddcc1 fwd="115.79.37.163" dyno= connect= service= status=503 bytes= protocol=https
2020-03-12T07:20:53.798943+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=dev-loc.herokuapp.com request_id=df48c384-d62e-4137-bb64-7ddd37c63e91 fwd="115.79.37.163" dyno= connect= service= status=503 bytes= protocol=https

Not able to connect mongodb

I just clone this repo following the steps. I'm getting an error on yarn dev

error: MongoDB connection error: MongoTimeoutError: Server selection timed out after 30000 ms
[nodemon] app crashed - waiting for file changes before starting...

Mongodb version Details

db version v4.0.13
git version: bda366f0b0e432ca143bc41da54d8732bd8d03c0
OpenSSL version: OpenSSL 1.1.1  11 Sep 2018
allocator: tcmalloc
modules: none
build environment:
    distmod: ubuntu1804
    distarch: x86_64
    target_arch: x86_64

Add Deployment options

We should have different options for deployment and they should be documented on README.md.

For starting I am thinking about choosing 2 or 3 of:

  • Simple VM: bash script + pm2
  • Heroku
  • Dokku
  • Kubernetes
  • Google cloud run
  • AWS Lambda
  • Azure functions
  • Netlify
  • Now.sh

Mongo Container is not starting on prod

Hey, guys!
Actively using the boilerplate, thank you, it is really good!

Locally application starts the MongoDB as service, everything is fine. But on production my image contains only app itself.

So I'm using the next deployment scheme:
Build machine:

  1. Build docker image for app
  2. Push to registry.
    Server:
  3. Pull image
  4. Run container.

But server only runs App container, not mongo.
Is there the short way to start app with mongo on prod by the scheme i'm using?

calling new RefreshToken from within the model gives problems

https://github.com/danielfsousa/express-rest-es2017-boilerplate/blob/032a005deaa68a06f476432f4d602917609a251a/src/api/models/refreshToken.model.js#L41

Hey Daniel, how's it going?
I was cleaning up my API based on your boilerplate, and after changing the export to be
module.exports = mongoose.model('RefreshToken', refreshTokenSchema); instead of

const RefreshToken = mongoose.model('RefreshToken', refreshTokenSchema);
module.exports = RefreshToken;

it broke (naturally) - I was thinking of we could improve this a bit by moving the new declaration in the controller?

Action button's href in passwordReset/passwordChange not rendering

Hi there!

Issue:
Previous versions of Pug/Jade supported an interpolation syntax such as:
a(href="/#{url}")
, but is not more supported in attributes.
Therefore, the link is not rendered properly in emai's action button.

Solution:
Changing following line in src/api/services/emails/passwordReset/html.pug
a.f-fallback.button.button--green(href=passwordResetUrl target='_blank' style='...')
to
a.f-fallback.button.button--green(href=passwordResetUrl target='_blank' style='...')
resolve the problem.

I may suggest a pullrequest if you wish.

Anyhow, have a good day :)

Docker deployment

Hi.
I'm currently looking to deploy the dockerized container to my server.
I cloned the repo, cd to the directory, yarn, cp .env.example .env and started the docker container with yarn docker:dev but it says NODE_ENV is missing from my .env file but I double checked and it exists, any ideas? Could you try to reproduce so I could see if the issue is only on my side.

Changes for v2

I am planning on doing a big refactoring on this repo, since the last update was 3 years ago.

  • Rename express-rest-es2017-boilerplate to express-rest-boilerplate
  • Use postgres as database (Postgres is a more reliable database and better suited for general purpose use)
  • Use Objection or Sequelize as ORM
  • Rafactor RBAC middleware
  • Use npm instead of yarn
  • Change folder structure
  • Replace apidoc with OpenAPI spec
  • Use pino for logging
  • Create a tutorial for deploying to kubernetes or a serverless platform
  • Remove semicolons =D
  • Remove Bluebird
  • Refactor unit and integration tests
  • Replace mocha, chai, sinon and nyc with jest
  • Add prettier
  • Update eslint-config
  • Update node to 12+
  • Update dependencies
  • Improve README
  • Remove unnecessary dependencies
  • Simple type checking in vscode without typescript (I will probably create another boilerplate for typescript + fastify)

What is the /v1/users/:id PUT api good for when you have v1/users/:id PATCH?

Why do you need the user-controller replace function and the /v1/users/:id PUT api when you have the user-controller update function and the /v1/users/:id PATCH api?
Is this just for the example use-case (some people like to use PUT and some like to use PATCH), or is there some deeper reasoning behind this decision, like supporting some official api standard (i.e. OAuth)?

dependency cycle not best practice

In this file we can see we require logger ('./../config/logger') which is a workaround from getting a dependency cycle warning, since logger is required in index.js as well (the entry point). Thus forming a dependency cycle.

Is this best practice? Would this cause an incomplete import from happening if this boilerplate was expanded upon in some instances?

Unhandled promise rejection

I believe it is coming from auth.js file. Any help is appreciated.

(node:7924) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Promise.promisify is not a function
(node:7924) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
onst error = err || info;
  console.log(req.logIn);
  const logIn = Promise.promisify(req.logIn);
  const apiError = new APIError({
    message: error ? error.message : 'Unauthorized',
    status: httpStatus.UNAUTHORIZED,
    stack: error ? error.stack : undefined,
  });

Add Swagger

Any refrence on how to enable swagger documentation on the express routes ?

Issue in user tests with _.some()

Hi,

In your tests you implement the following function:

async function format(user) {
    const formated = user;
    // delete password
    delete formated.password;
    // get users from database
    const dbUser = (await User.findOne({ email: user.email })).transform();
    // remove null and undefined properties
    return omitBy(dbUser, isNil);
}

then you use it in _.some() to check if an object is included in res.body:

const bran = format(dbUsers.branStark);
const john = format(dbUsers.jonSnow);

const includesBranStark = some(res.body, bran);
const includesjonSnow = some(res.body, john);

Since format() is an async function, it returns a Promise, and when used as a predicate in _.some(), it will always return true, which makes the test incorrect.

Best way to run command line tasks

I would like to run several tasks in the server like cron or manually executed ones (like creating a super user after first install), how do you suggest to implement it?

I prefer not to deal with API calls directly since most of the commands runs on bash one liners (like a cron command).

API Documentation

Hi @danielfsousa

Thanks for all your hard work on the REST Boilerplate. I used it as the basis for my company's API. I also used it as example content for my blog post about creating API documentation using Squarespace. Here is the blog post, and here is the boilerplate API reference. If you'd like, I could clean up the reference so that you can reference it on your README. Just let me know.

Regards,

John

Is there any hosting that supports Node 7+ ?

Hey, I was just trying to run the tests and noticed async fails because I am running Node 6.x on my system.
I noticed you mention 7.x+ as requirements but before upgrading I went on to see if there's any hosting provider covering the newest Node versions and to my surprise several only support 4.x or max 6.x .. (like AWS for example)
How hard would be to re-write the parts of the boilerplate needed for >6.x node? (I imagine async/await)

Can get it to run

yarn dev v0.15.1 $ "nodemon ./src/index.js" sh: 1: nodemon ./src/index.js: not found error Command failed with exit code 127.

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml
  • The new Node.js version is in-range for the engines in 1 of your package.json files, so that was left alone

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

wrong test:watch path

"test:watch": "cross-env NODE_ENV=test mocha --watch src/api/tests/unit",
should be "test:watch": "cross-env NODE_ENV=test mocha --watch src/api/tests/integration",

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.