Need a unique gift idea?
A Pastebin account makes a great Christmas gift
SHARE
TWEET

Untitled

a guest Feb 23rd, 2018 82 Never
Upgrade to PRO!
ENDING IN00days00hours00mins00secs
 
  1. 'use strict';
  2. const express = require('express');
  3. const bodyParser = require('body-parser');
  4.  
  5. const {User} = require('./models');
  6.  
  7. const router = express.Router();
  8.  
  9. const jsonParser = bodyParser.json();
  10.  
  11. // Post to register a new user
  12. router.post('/', jsonParser, (req, res) => {
  13.   const requiredFields = ['username', 'password'];
  14.   const missingField = requiredFields.find(field => !(field in req.body));
  15.  
  16.   if (missingField) {
  17.     return res.status(422).json({
  18.       code: 422,
  19.       reason: 'ValidationError',
  20.       message: 'Missing field',
  21.       location: missingField
  22.     });
  23.   }
  24.  
  25.   const stringFields = ['username', 'password', 'firstName', 'lastName'];
  26.   const nonStringField = stringFields.find(
  27.     field => field in req.body && typeof req.body[field] !== 'string'
  28.   );
  29.  
  30.   if (nonStringField) {
  31.     return res.status(422).json({
  32.       code: 422,
  33.       reason: 'ValidationError',
  34.       message: 'Incorrect field type: expected string',
  35.       location: nonStringField
  36.     });
  37.   }
  38.  
  39.   // If the username and password aren't trimmed we give an error.  Users might
  40.   // expect that these will work without trimming (i.e. they want the password
  41.   // "foobar ", including the space at the end).  We need to reject such values
  42.   // explicitly so the users know what's happening, rather than silently
  43.   // trimming them and expecting the user to understand.
  44.   // We'll silently trim the other fields, because they aren't credentials used
  45.   // to log in, so it's less of a problem.
  46.   const explicityTrimmedFields = ['username', 'password'];
  47.   const nonTrimmedField = explicityTrimmedFields.find(
  48.     field => req.body[field].trim() !== req.body[field]
  49.   );
  50.  
  51.   if (nonTrimmedField) {
  52.     return res.status(422).json({
  53.       code: 422,
  54.       reason: 'ValidationError',
  55.       message: 'Cannot start or end with whitespace',
  56.       location: nonTrimmedField
  57.     });
  58.   }
  59.  
  60.   const sizedFields = {
  61.     username: {
  62.       min: 1
  63.     },
  64.     password: {
  65.       min: 10,
  66.       // bcrypt truncates after 72 characters, so let's not give the illusion
  67.       // of security by storing extra (unused) info
  68.       max: 72
  69.     }
  70.   };
  71.   const tooSmallField = Object.keys(sizedFields).find(
  72.     field =>
  73.       'min' in sizedFields[field] &&
  74.             req.body[field].trim().length < sizedFields[field].min
  75.   );
  76.   const tooLargeField = Object.keys(sizedFields).find(
  77.     field =>
  78.       'max' in sizedFields[field] &&
  79.             req.body[field].trim().length > sizedFields[field].max
  80.   );
  81.  
  82.   if (tooSmallField || tooLargeField) {
  83.     return res.status(422).json({
  84.       code: 422,
  85.       reason: 'ValidationError',
  86.       message: tooSmallField
  87.         ? `Must be at least ${sizedFields[tooSmallField]
  88.           .min} characters long`
  89.         : `Must be at most ${sizedFields[tooLargeField]
  90.           .max} characters long`,
  91.       location: tooSmallField || tooLargeField
  92.     });
  93.   }
  94.  
  95.   let {username, password, firstName = '', lastName = ''} = req.body;
  96.   // Username and password come in pre-trimmed, otherwise we throw an error
  97.   // before this
  98.   firstName = firstName.trim();
  99.   lastName = lastName.trim();
  100.  
  101.   return User.find({username})
  102.     .count()
  103.     .then(count => {
  104.       if (count > 0) {
  105.         // There is an existing user with the same username
  106.         return Promise.reject({
  107.           code: 422,
  108.           reason: 'ValidationError',
  109.           message: 'Username already taken',
  110.           location: 'username'
  111.         });
  112.       }
  113.       // If there is no existing user, hash the password
  114.       return User.hashPassword(password);
  115.     })
  116.     .then(hash => {
  117.       return User.create({
  118.         username,
  119.         password: hash,
  120.         firstName,
  121.         lastName
  122.       });
  123.     })
  124.     .then(user => {
  125.       return res.status(201).json(user.serialize());
  126.     })
  127.     .catch(err => {
  128.       // Forward validation errors on to the client, otherwise give a 500
  129.       // error because something unexpected has happened
  130.       if (err.reason === 'ValidationError') {
  131.         return res.status(err.code).json(err);
  132.       }
  133.       res.status(500).json({code: 500, message: 'Internal server error'});
  134.     });
  135. });
  136.  
  137. // Never expose all your users like below in a prod application
  138. // we're just doing this so we have a quick way to see
  139. // if we're creating users. keep in mind, you can also
  140. // verify this in the Mongo shell.
  141. router.get('/', (req, res) => {
  142.   return User.find()
  143.     .then(users => res.json(users.map(user => user.serialize())))
  144.     .catch(err => res.status(500).json({message: 'Internal server error'}));
  145. });
  146.  
  147. module.exports = {router};
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top