import crypto from 'crypto'
<%_ if (passwordSignup) { _%>
import bcrypt from 'bcrypt'
<%_ if (authServices.length) { _%>
import randtoken from 'rand-token'
<%_ } _%>
<%_ } _%>
import mongoose, { Schema } from 'mongoose'
import mongooseKeywords from 'mongoose-keywords'
<%_ if (passwordSignup) { _%>
import { env } from '../../config'
<%_ } _%>

<%_ if (passwordSignup) { _%>
const compare = require('bluebird').promisify(bcrypt.compare)
<%_ } _%>
const roles = ['user', 'admin']

const userSchema = new Schema({
  email: {
    type: String,
    match: /^\S+@\S+\.\S+$/,
    required: true,
    unique: true,
    trim: true,
    lowercase: true
  },
  <%_ if (passwordSignup) { _%>
  password: {
    type: String,
    required: true,
    minlength: 6
  },
  <%_ } _%>
  name: {
    type: String,
    index: true,
    trim: true
  },
  <%_ if (authServices.length) { _%>
  services: {
    <%- authServices.map(function(service) {
      return service + ': String'
    }).join(',\n') %>
  },
  <%_ } _%>
  role: {
    type: String,
    enum: roles,
    default: 'user'
  },
  picture: {
    type: String,
    trim: true
  }
}, {
  timestamps: true
})

userSchema.path('email').set(function (email) {
  if (!this.picture || this.picture.indexOf('https://gravatar.com') === 0) {
    const hash = crypto.createHash('md5').update(email).digest('hex')
    this.picture = `https://gravatar.com/avatar/${hash}?d=identicon`
  }

  if (!this.name) {
    this.name = email.replace(/^(.+)@.+$/, '$1')
  }

  return email
})

<%_ if (passwordSignup) { _%>
userSchema.pre('save', function (next) {
  if (!this.isModified('password')) return next()

  /* istanbul ignore next */
  const rounds = env === 'test' ? 1 : 9

  bcrypt.hash(this.password, rounds, (err, hash) => {
    /* istanbul ignore next */
    if (err) return next(err)
    this.password = hash
    next()
  })
})

<%_ } _%>
userSchema.methods = {
  view (full) {
    let view = {}
    let fields = ['id', 'name', 'picture']

    if (full) {
      fields = [...fields, 'email', 'createdAt']
    }

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

    return view
  }<%_ if (passwordSignup) { _%>,

  authenticate (password) {
    return compare(password, this.password).then((valid) => valid ? this : false)
  }
  <%_ } _%>
}

userSchema.statics = {
  <%_ if (authServices.length) { _%>
  roles,

  createFromService ({ service, id, email, name, picture }) {
    return this.findOne({ $or: [{ [`services.${service}`]: id }, { email }] }).then((user) => {
      if (user) {
        user.services[service] = id
        user.name = name
        user.picture = picture
        return user.save()
      } else {
        <%_ if (passwordSignup) { _%>
        const password = randtoken.generate(16)
        <%_ } _%>
        return this.create({ services: { [service]: id }, email<% if (passwordSignup) { %>, password<% } %>, name, picture })
      }
    })
  }
  <%_ } else { _%>
  roles
  <%_ } _%>
}

userSchema.plugin(mongooseKeywords, { paths: ['email', 'name'] })

export default mongoose.model('User', userSchema)

@@ -882,17 +882,17 @@
 %7B%0A    %3C%25
--
+_
  authSer
@@ -901,11 +901,15 @@
 ces.
-map
+forEach
 (fun
@@ -917,16 +917,17 @@
 tion
+ 
 (service
 ) %7B%0A
@@ -926,65 +926,105 @@
 vice
-) %7B%0A      return service + ': String'%0A    %7D).join(',%5Cn') 
+, i) %7B _%25%3E%0A    %3C%25= service %25%3E: String%3C%25- i !== authServices.length - 1 ? ',' : '' %25%3E%0A    %3C%25_ %7D) _
 %25%3E%0A 

Fix user model indentation