GithubHelp home page GithubHelp logo

kasvith / express-mongo-jwt-boilerplate Goto Github PK

View Code? Open in Web Editor NEW
103.0 8.0 43.0 337 KB

Express Mongo JsonWebToken boilerplate

JavaScript 94.00% Dockerfile 3.10% Shell 2.89%
express node mongo passport jwt auth boilerplate boilerplate-template api mongodb

express-mongo-jwt-boilerplate's Introduction

Express Mongo JWT Boilerplate Build Status

Installation

  • Install NodeJS, MongoDB
  • Install npm or yarn
  • Rename .env.example to .env
  • Fulfill .env data
  • Start MongoDB
  • Run yarn run dev or npm run dev
  • Check http://localhost:3000/api/status to see it works

With Docker

  • Make sure you have installed Docker and Docker Compose
  • Just run docker-compose up to start the server

Configuration

Name Description Example
NODE_ENV Environment for node js "dev", "prod", "test"
APP Name of the application My cool express app
PORT Port to run the application (if you run in heroku this will setup automatically) 3000
HOSTNAME Host name for running the application http://localhost:3000
APP_SECRET Secret for running app. Use a strong hash in production and make sure to rotate it ddd36434-80fe-4f18-b3b6-e645697f7b84
MONGOURI MongoDB connection URI mongodb://localhost:27017/yourapp
MONGOTESTURI MongoDB connection URI for testing mongodb://localhost:27017/test-app
TRANSPORTER_HOST Mail server host smtp.mymailer.com
TRANSPORTER_PORT Mail server port 2525
TRANSPORTER_USERNAME Mail server username harrypotter
TRANSPORTER_PASSWORD Mail server password alohomora

express-mongo-jwt-boilerplate's People

Contributors

d0pecode avatar dependabot[bot] avatar kasvith avatar namila007 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

express-mongo-jwt-boilerplate's Issues

Refresh and access token

@kasvith what do you think about implementing refresh token which would be stored in mongo and would be "refreshed" on every user call so we could write service which would check when last call was and not allow action if for example last call was few hours ago (expire access token)?

Return user data with token

Hi Kasun,

thank you very much for this fantastic boilerplate! ๐Ÿ‘
It really helps me to dive into MongoDB/Mongoose.

I have a question about what the best approach would be for a GET route like /profile to get the user data after successfully log in.

After the login the API returns an JWT token. Can I search with that for my user to get all my data back?

Normally I did that with session cookies like findById(req.session.id) but I never did something like this with a JWT token. ๐Ÿ˜„

Deprecation warnings

We have two deprecation warnings:

  • DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.

  • DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.

I created PR with fix #14.


Edit

I also updated dependencies.

Email Already Taken

When you hit http:localhost:3000/api/auth/register with the same email, as expected it will kick back an error that says that email is already taken. I propose updating this to

  1. checking to see if this user is already active
  2. if they are not active, you send another generated link to their email.

Reasoning: currently if someone was to send a post request to this server with my email, it has ruined the experience for me as the user. Now I have to reset password? Which currently does not exist in this project. So this is a blindspot.

[Discussion] Introducing a powerful role management system

Currently we don't have a role management system. We have admin and user. But that's not it.

While developing applications its often to have multiple roles and allow access based on roles. Roles does inherit properties like an admin can do what an editor can do for sure but not otherway around.

It would be better if we could introduce a nice role management system where users can add roles and manage roles

DDoS protection

It is boilerplate so such common technique like basic DDoS protection should be also packed within. There is number of npm modules which make it very easy. @kasvith I will implement and create PR.

Email confirmation after registration

I implemented email confirmation feature in my fork but before I create new PR I have question.

What does this code do?

userSchema.method({
  transform () {
    const transformed = {}
    const fields = ['id', 'name', 'email', 'createdAt', 'activationKey', 'role']

    fields.forEach((field) => {
      transformed[field] = this[field]
    })

    return transformed
  },

  passwordMatches (password) {
    return bcrypt.compareSync(password, this.password)
  }
})

I'm sending mail in .post mongoose hook and I don't know if I should add following code to it:

if (!this.isModified('activationKey')) {
  console.log('Not modified.. but what does it mean?')
  return next()
}

Also second question - because currently I'm sending email and have /cofirm endpoint to set active to true but I'm not checking if user active when login. What is most convienient place to check it?In controller or in findAndGenerateToken function? Or maybe somewhere else?


While waiting for reply, for now I just added this line

if (!user.active) throw new APIError(`User not activated`, httpStatus.UNAUTHORIZED)

to findAndGenerateToken function.

Thanks for the code- and a question about the async-await usage

hi,
I found your boiler plate very helpful, thanks.

I have a question, why did you use asyn in the user.model.js file, but there's no "await" inside the function.
just curious.
for example - here:

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

this.password = bcrypt.hashSync(this.password)

return next()

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

mail template feature

We should also provide our boilerplate with mail template that would be a nice feature.

Email Templates

It would be better if we could integrate templates for emails. Currently, we use a hardcoded email.
Also, we need to give config to the user to be able to change from address of emails.

Customizing email engines would be nice also via config

Reset password feature

As our boilerplate already has user /register, /login and /cofirm routes we should also provide /reset route to reset password.

Move Schema.method transform to external file

I want to move methods from this code:

adminSchema.method({
  transform () {
    const transformed = {}
    const fields = ['id', 'name', 'email', 'createdAt']
    fields.forEach((field) => { transformed[field] = this[field] })
    return transformed
  },

  passwordMatches (password) {
    return bcrypt.compareSync(password, this.password)
  }
})

to external files. That's because I'm using transform also in second model and most of the code is just repeated. Perfect solution would be to create property with fields array then assign transform method to required function in which I would use .this keyword to access fields.

//user.model.js
const transformFields = require('./utils/transformFields.js')
...

userSchema.method({
  fields: ['id', 'name', 'email', 'createdAt'],
  transform: transformFields

//transformFields.js
function transform() {

    const transformed = {}

    this.fields.forEach((field) => {
      transformed[field] = this[field]
    })

    return transformed
  },

Unfortunetally when I call register enpoint above code is giving me some weird response:

{
"message": "schema.methods[method][k].bind is not a function",
"errors": {}
}

I don't know what does it mean, maybe schema.method({}) can contain only functions, not properties like fields array. I tried to simplify above to just this:

userSchema.method({
  fields: ['id', 'name', 'email', 'createdAt'],
  transform: function () {
    const transformed = {}

    this.fields.forEach((field) => {
      transformed[field] = this[field]
    })

    return transformed
  },

in order to check if it's problem with requiring external method but above is also giving me same response when register endpoint is called.

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.