All files / app/models/user user.ts

100% Statements 15/15
50% Branches 1/2
100% Functions 4/4
100% Lines 15/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 1681x 1x 1x 1x 1x               1x                                                                                                                     7x             1x               1x 347x   346x   1x                 1x             1x                                                                                                                     1x  
import {Model, DataTypes} from 'sequelize';
import {default as sequelize} from '@db';
import bcrypt from 'bcrypt';
import config from '@config';
import {PasswordNotHashableError} from '@errors';
import {ModelHooks} from 'sequelize/types/lib/hooks';
 
/**
 * Model class for users.
 *
 * Represents a column of the table 'users' in the database
 */
export class User extends Model {
  /**
   * The id of the user.
   *
   * Primary key.
   */
  public id!: number;
 
  /**
   * Username (not email).
   *
   * Is unique
   */
  public username!: string;
 
  /**
   * Email of the user.
   *
   * Is not allowed to be null or empty
   */
  public email!: string;
 
  /**
   * Password of the user, is hashed with bcrypt.
   *
   * Is not allowed to be null or empty
   */
  public password!: string;
 
  /**
   * Whether or not the user has access to the beta build.
   *
   * The default value is false and is never updated by a client request.
   */
  public isBetaUser!: boolean;
 
  // Timestamps
  /**
   * The date and time the user was created
   */
  public readonly createdAt!: Date;
 
  /**
   * The date and time the user was updated
   */
  public readonly updatedAt!: Date;
 
  /**
   * The date and time the user was deleted
   */
  public readonly deletedAt!: Date;
 
  /**
   * Search for a user by the given username.
   *
   * Only returns one instance if multiple exist.
   * @param username - The username of the user to find
   */
  public static findByUsername(username: string): Promise<User | null> {
    return this.findOne({where: {username}});
  }
 
  /**
   * List of attributes which should be used if a user
   * reference is eagerly loaded.
   */
  public static simpleAttributes = ['id', 'username'];
}
 
/**
 * Sets the password of the user to it's salted hash.
 * @param user    - The user for which to hash the password
 * @param options - Options
 */
export const hashPasswordOfUser = (user: User): Promise<void> => {
  return bcrypt.hash(user.password + '', config.auth.saltRounds)
      .then((hash: string) => {
        user.password = hash;
      }).catch(() => {
        throw new PasswordNotHashableError(user.username);
      });
};
 
/**
 * Create hooks for user model.
 *
 * Will be used when initializing the model.
 */
const hooks: Partial<ModelHooks> = {
  beforeSave: hashPasswordOfUser,
};
 
/**
 * Initialize user model
 */
User.init(
    {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: DataTypes.INTEGER,
      },
      username: {
        type: DataTypes.STRING(config.user.maxUsernameLength || 25),
        allowNull: false,
        unique: true,
        validate: {
          notEmpty: true,
          min: 4,
          max: 25,
          notContains: ' ',
        },
      },
      password: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          notEmpty: true,
          min: 6,
        },
      },
      email: {
        type: DataTypes.STRING,
        allowNull: false,
        validate: {
          isEmail: true,
          notEmpty: true,
        },
      },
      isBetaUser: {
        type: DataTypes.BOOLEAN,
        defaultValue: false,
      },
      createdAt: {
        allowNull: false,
        type: DataTypes.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: DataTypes.DATE,
      },
      deletedAt: {
        type: DataTypes.DATE,
      },
    },
    {
      sequelize,
      modelName: 'user',
      hooks,
      timestamps: true,
      paranoid: true,
    });
 
export default User;