This polyfill was added because node versions less than 10.5.0 didn't include scrypt support. As we now raised the minimum required version to 12.0.0, this polyfill isn't needed anymore. Signed-off-by: Erik Michelson <opensource@erik.michelson.eu>
		
			
				
	
	
		
			166 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict'
 | |
| // external modules
 | |
| const Sequelize = require('sequelize')
 | |
| const scrypt = require('scrypt-kdf')
 | |
| 
 | |
| // core
 | |
| const logger = require('../logger')
 | |
| const { generateAvatarURL } = require('../letter-avatars')
 | |
| 
 | |
| module.exports = function (sequelize, DataTypes) {
 | |
|   const User = sequelize.define('User', {
 | |
|     id: {
 | |
|       type: DataTypes.UUID,
 | |
|       primaryKey: true,
 | |
|       defaultValue: Sequelize.UUIDV4
 | |
|     },
 | |
|     profileid: {
 | |
|       type: DataTypes.STRING,
 | |
|       unique: true
 | |
|     },
 | |
|     profile: {
 | |
|       type: DataTypes.TEXT
 | |
|     },
 | |
|     history: {
 | |
|       type: DataTypes.TEXT
 | |
|     },
 | |
|     accessToken: {
 | |
|       type: DataTypes.TEXT
 | |
|     },
 | |
|     refreshToken: {
 | |
|       type: DataTypes.TEXT
 | |
|     },
 | |
|     deleteToken: {
 | |
|       type: DataTypes.UUID,
 | |
|       defaultValue: Sequelize.UUIDV4
 | |
|     },
 | |
|     email: {
 | |
|       type: Sequelize.TEXT,
 | |
|       validate: {
 | |
|         isEmail: true
 | |
|       }
 | |
|     },
 | |
|     password: {
 | |
|       type: Sequelize.TEXT
 | |
|     }
 | |
|   })
 | |
| 
 | |
|   User.prototype.verifyPassword = function (attempt) {
 | |
|     return scrypt.verify(Buffer.from(this.password, 'hex'), attempt)
 | |
|   }
 | |
| 
 | |
|   User.associate = function (models) {
 | |
|     User.hasMany(models.Note, {
 | |
|       foreignKey: 'ownerId',
 | |
|       constraints: false
 | |
|     })
 | |
|     User.hasMany(models.Note, {
 | |
|       foreignKey: 'lastchangeuserId',
 | |
|       constraints: false
 | |
|     })
 | |
|   }
 | |
|   User.getProfile = function (user) {
 | |
|     if (!user) {
 | |
|       return null
 | |
|     }
 | |
|     return user.profile ? User.parseProfile(user.profile) : (user.email ? User.parseProfileByEmail(user.email) : null)
 | |
|   }
 | |
|   User.parseProfile = function (profile) {
 | |
|     try {
 | |
|       profile = JSON.parse(profile)
 | |
|     } catch (err) {
 | |
|       logger.error(err)
 | |
|       profile = null
 | |
|     }
 | |
|     if (profile) {
 | |
|       profile = {
 | |
|         name: profile.displayName || profile.username,
 | |
|         photo: User.parsePhotoByProfile(profile),
 | |
|         biggerphoto: User.parsePhotoByProfile(profile, true)
 | |
|       }
 | |
|     }
 | |
|     return profile
 | |
|   }
 | |
|   User.parsePhotoByProfile = function (profile, bigger) {
 | |
|     let photo = null
 | |
|     switch (profile.provider) {
 | |
|       case 'facebook':
 | |
|         photo = 'https://graph.facebook.com/' + profile.id + '/picture'
 | |
|         if (bigger) photo += '?width=400'
 | |
|         else photo += '?width=96'
 | |
|         break
 | |
|       case 'twitter':
 | |
|         photo = 'https://twitter.com/' + profile.username + '/profile_image'
 | |
|         if (bigger) photo += '?size=original'
 | |
|         else photo += '?size=bigger'
 | |
|         break
 | |
|       case 'github':
 | |
|         photo = 'https://avatars.githubusercontent.com/u/' + profile.id
 | |
|         if (bigger) photo += '?s=400'
 | |
|         else photo += '?s=96'
 | |
|         break
 | |
|       case 'gitlab':
 | |
|         photo = profile.avatarUrl
 | |
|         if (photo) {
 | |
|           if (bigger) photo = photo.replace(/(\?s=)\d*$/i, '$1400')
 | |
|           else photo = photo.replace(/(\?s=)\d*$/i, '$196')
 | |
|         } else {
 | |
|           photo = generateAvatarURL(profile.username)
 | |
|         }
 | |
|         break
 | |
|       case 'mattermost':
 | |
|         photo = profile.avatarUrl
 | |
|         if (photo) {
 | |
|           if (bigger) photo = photo.replace(/(\?s=)\d*$/i, '$1400')
 | |
|           else photo = photo.replace(/(\?s=)\d*$/i, '$196')
 | |
|         } else {
 | |
|           photo = generateAvatarURL(profile.username)
 | |
|         }
 | |
|         break
 | |
|       case 'dropbox':
 | |
|         photo = generateAvatarURL('', profile.emails[0].value, bigger)
 | |
|         break
 | |
|       case 'google':
 | |
|         photo = profile.photos[0].value
 | |
|         if (bigger) photo = photo.replace(/(\?sz=)\d*$/i, '$1400')
 | |
|         else photo = photo.replace(/(\?sz=)\d*$/i, '$196')
 | |
|         break
 | |
|       case 'ldap':
 | |
|         photo = generateAvatarURL(profile.username, profile.emails[0], bigger)
 | |
|         break
 | |
|       case 'saml':
 | |
|         photo = generateAvatarURL(profile.username, profile.emails[0], bigger)
 | |
|         break
 | |
|       default:
 | |
|         photo = generateAvatarURL(profile.username)
 | |
|         break
 | |
|     }
 | |
|     return photo
 | |
|   }
 | |
|   User.parseProfileByEmail = function (email) {
 | |
|     return {
 | |
|       name: email.substring(0, email.lastIndexOf('@')),
 | |
|       photo: generateAvatarURL('', email, false),
 | |
|       biggerphoto: generateAvatarURL('', email, true)
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   function updatePasswordHashHook (user, options) {
 | |
|     // suggested way to hash passwords to be able to do this asynchronously:
 | |
|     // @see https://github.com/sequelize/sequelize/issues/1821#issuecomment-44265819
 | |
| 
 | |
|     if (!user.changed('password')) {
 | |
|       return Promise.resolve()
 | |
|     }
 | |
| 
 | |
|     return scrypt.kdf(user.getDataValue('password'), { logN: 15 }).then(keyBuf => {
 | |
|       user.setDataValue('password', keyBuf.toString('hex'))
 | |
|     })
 | |
|   }
 | |
| 
 | |
|   User.beforeCreate(updatePasswordHashHook)
 | |
|   User.beforeUpdate(updatePasswordHashHook)
 | |
| 
 | |
|   return User
 | |
| }
 |