Skip to content
This repository has been archived by the owner on Feb 17, 2021. It is now read-only.

Latest commit

Β 

History

History
202 lines (176 loc) Β· 4.35 KB

lecture.md

File metadata and controls

202 lines (176 loc) Β· 4.35 KB

Lecture 16

const userSchema = new mongoose.Schema({
  fullName: {
    type: String,
    required: true
  },
  email: {
    type: String,
    unique: '{VALUE} is already exist!',
    required: true,
    validate: {
      validator: function checkEmail(value) {
        const re = /^(\S+)@([a-z0-9-]+)(\.)([a-z]{2,4})(\.?)([a-z]{0,4})+$/;
        return re.test(value);
      },
      message: props => `${ props.value } is not a valid email.`
    },
  },
  photo: {
    type: String,
    default: config.get('aws').defaultUserPhoto
  },
  passwordHash: {
    type: String
  },
  salt: {
    type: String
  }
});
userSchema.virtual('password')
  .set(function (password) {
    if (!password) {
      this.invalidate('password', 'Password can\'t be empty!');
    }

    if (password !== undefined) {
      if (password.length < 6) {
        this.invalidate('password', 'Password can\'t be less than 6 symbols!');
      }
    }

    this._plainPassword = password;

    if (password) {
      this.salt = crypto.randomBytes(config.get('crypto').hash.length).toString('base64');
      this.passwordHash = crypto.pbkdf2Sync(
        password,
        this.salt,
        config.get('crypto').hash.iterations,
        config.get('crypto').hash.length,
        'sha1'
      ).toString('base64');
    } else {
      this.salt = undefined;
      this.passwordHash = undefined;
    }
  })
  .get(function () {
    return this._plainPassword;
  });
userSchema.methods.checkPassword = function (password) {
  if (!password) return false;
  if (!this.passwordHash) return false;

  return crypto.pbkdf2Sync(
    password,
    this.salt,
    config.get('crypto').hash.iterations,
    config.get('crypto').hash.length,
    'sha1').toString('base64') === this.passwordHash;
};
userSchema.methods.getAuthData = function () {
  const payload = {
    id: this._id,
    email: this.email
  };
  return {
    token: jwt.encode(payload, config.get('jwtSecret')),
    user: {
      fullName: this.fullName,
      photo: this.photo
    }
  };
};
const passport = require('koa-passport');

passport.use(require('./jwtStrategy'));
passport.use(require('./localStrategy'));

module.exports = passport;
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const config = require('config');

const User = require('../../accounts/models/user');


let opts = {
  jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('JWT'),
  secretOrKey: config.get('jwtSecret'),
};

module.exports = new JwtStrategy(opts, function (jwt_payload, done) {
  User.findById(jwt_payload.id, function (err, user) {
    if (err) {
      return done(err, false);
    }
    if (user) {
      return done(null, user);
    } else {
      return done(null, false);
    }
  });
});
let LocalStrategy = require('passport-local');
let User = require('../../accounts/models/user');

let opts = {
  usernameField: 'email',
  passwordField: 'password',
  passReqToCallback: true,
  session: false
};

module.exports = new LocalStrategy(opts, (req, email, password, done) => {
  User.findOne({ email: email }, (err, user) => {
    if (err) {
      return done(err);
    }
    if (!user) {
      return done('User doesn\'t exist!', false);
    }
    if (!user.checkPassword(password)) {
      return done('Incorrect password!', false);
    }
    return done(null, user);
  });
});
const passport = require('../libs/passport');

module.exports = passport.initialize();
exports.auth = async (ctx, next) => {
  await passport.authenticate('local', (err, user) => {
    if (user) {
      ctx.body = user.getAuthData();
    } else {
      ctx.status = 400;
      if (err) {
        ctx.body = { error: err };
      }
    }
  })(ctx, next);
};

exports.signUp = async ctx => {
  const body = ctx.request.body;
  let user = new User({
    fullName: body.fullName,
    email: body.email,
    password: body.password,
    role: 'Admin'
  });
  await user.save();
  ctx.body = user.getAuthData();
};