Newer
Older
const timestamps = require('./properties/timestamps')
module.exports = (sequelize, DataTypes) => {
const Model = sequelize.define('User', Object.assign(
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
name: {
type: DataTypes.TEXT,
},
email: {
type: DataTypes.TEXT,
},
password: {
type: DataTypes.TEXT,
},
reset_token: {
type: DataTypes.TEXT,
},
meta: {
type: DataTypes.JSONB,
}
},
timestamps(DataTypes),
), {
paranoid: true,
tableName: 'users',
})
Model.getPolyIdentifier = () => 'user'
Model.getRelationIdentifier = () => 'users'
Model.prototype.toJSON = function userToJSON() {
const age = this.hasOwnProperty('age') ? { age: this.age } : { }
if (meta.hasOwnProperty('dob')) {
delete meta.dob
}
return {
id: this.id,
name: this.name,
email: this.email,
created_at: this.created_at,
updated_at: this.updated_at,
}
}
Model.prototype.setPlaintextPassword = async function(password) {
const crypto = require('core/utils/crypto')
this.setDataValue('password', await crypto.hash(password))
}
Model.prototype.asToken = async function() {
const crypto = require('core/utils/crypto')
return await crypto.encrypt(JSON.stringify({ session: this.id }))
}
Model.fromToken = async function(token) {
const crypto = require('core/utils/crypto')
const { session } = JSON.parse(await crypto.decrypt(token))
return Model.findOne({ where: { id: session } })
}
Model.prototype.checkPassword = async function(password) {
const crypto = require('core/utils/crypto')
if (this.password == null) {
return false
}
return await crypto.verify(this.password, password)
}
Model.prototype.generateResetToken = async function() {
const crypto = require('core/utils/crypto')
const moment = require('moment')
const id = this.id
const expires = moment.utc()
.add(1, 'hour')
.toISOString()
const token = await crypto.encrypt(JSON.stringify({ id, expires }))
this.reset_token = token
await this.save()
return token
}
Model.createSystemUser = async function() {
const crypto = require('core/utils/crypto')
const user = Model.build({
id: '00000000-0000-0000-0000-000000000000',
name: 'System',
email: 'louis@microhacks.co.uk',
})
await user.setPlaintextPassword(await crypto.secureHexString(32))
await user.save()
return user
}
Model.register = async function(args) {
const user = Model.build(args)
await user.setPlaintextPassword(args.password)
await user.save()
return user
}
Model.prototype.handleIncludes = async function(includes, loaders = null) {
const inc = new Set(includes)
if (inc.has('user_age')) {
this.age = await this.getAge()
}
}
Model.prototype.getAge = async function getUserAge() {
const [ userAge ] = await Model.sequelize.query(`
SELECT
CASE
WHEN meta -> 'dob' IS NOT NULL THEN
age(concat_ws('/', meta -> 'dob' ->> 'day', meta -> 'dob' ->> 'month', meta -> 'dob' ->> 'year')::timestamptz)
END AS age
FROM users
WHERE id = :userId
LIMIT 1
`, {
replacements: { userId: this.id },
type: sequelize.QueryTypes.SELECT,
return (userAge && userAge.age) ? (userAge.age.years < 18 ? 'youth' : 'adult') : 'youth'
Model.associate = function defineModelAssociations(models) {
Model.hasMany(models.AuthorizationCode, { foreignKey: 'user_id' })
Model.hasMany(models.OAuthClient, { foreignKey: 'owner_id' })
Model.hasMany(models.AccessToken, { foreignKey: 'user_id' })
Model.hasMany(models.RefreshToken, { foreignKey: 'user_id' })
Model.hasMany(models.File, { foreignKey: 'user_id' })
Model.belongsToMany(models.File, { as: 'likes', through: 'user_file_likes', foreignKey: 'user_id', otherKey: 'file_id' })

Louis
committed
Model.belongsToMany(models.BundleCode, { through: 'user_bundle_codes', foreignKey: 'user_id', otherKey: 'bundle_code_id', timestamps: false })