Mirror of https://github.com/roostorg/coop github.com/roostorg/coop
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 156 lines 4.4 kB view raw
1import { promisify } from 'util'; 2import bcrypt from 'bcryptjs'; 3import sequelize, { 4 type CreationOptional, 5 type HasManyAddAssociationsMixin, 6 type HasManyGetAssociationsMixin, 7 type HasManyRemoveAssociationsMixin, 8 type InferAttributes, 9 type InferCreationAttributes, 10 type Sequelize, 11} from 'sequelize'; 12 13import { type DataTypes } from './index.js'; 14import { getPermissionsForRole, UserRole } from './types/permissioning.js'; 15 16const { Model } = sequelize; 17const bcryptCompare = promisify(bcrypt.compare); 18 19export type User = InstanceType<ReturnType<typeof makeUserModel>>; 20 21/** 22 * Data Model for Users. Users are Coop users who have 23 * created profiles on our website. Actors (see ActorModel.js) 24 * are users on the organization's platforms that upload potentially 25 * problematic content. 26 */ 27const makeUserModel = (sequelize: Sequelize, DataTypes: DataTypes) => { 28 class User extends Model< 29 InferAttributes<User, { omit: 'createdAt' | 'updatedAt' }>, 30 InferCreationAttributes<User, { omit: 'createdAt' | 'updatedAt' }> 31 > { 32 public declare id: string; 33 public declare email: string; 34 public declare password: string | null; 35 public declare firstName: string; 36 public declare lastName: string; 37 public declare orgId: string; 38 public declare role: CreationOptional<UserRole>; 39 public declare approvedByAdmin: CreationOptional<boolean>; 40 public declare rejectedByAdmin: CreationOptional<boolean>; 41 public declare createdAt: Date; 42 public declare updatedAt: Date; 43 public declare loginMethods: ('password' | 'saml')[]; 44 45 // Have to use any below to avoid circular type errors 46 /* eslint-disable @typescript-eslint/no-explicit-any */ 47 public declare addFavoriteRules: HasManyAddAssociationsMixin<any, string>; 48 public declare removeFavoriteRules: HasManyRemoveAssociationsMixin< 49 any, 50 string 51 >; 52 public declare getFavoriteRules: HasManyGetAssociationsMixin<any>; 53 /* eslint-enable @typescript-eslint/no-explicit-any */ 54 55 // eslint-disable-next-line @typescript-eslint/no-explicit-any 56 static associate(models: { [key: string]: any }) { 57 User.belongsTo(models.Org, { as: 'Org' }); 58 User.hasMany(models.Rule, { as: 'Rules', foreignKey: 'creatorId' }); 59 User.hasMany(models.LocationBank, { 60 as: 'LocationBanks', 61 foreignKey: 'ownerId', 62 }); 63 User.hasMany(models.Backtest, { 64 as: 'Backtests', 65 foreignKey: 'creatorId', 66 }); 67 User.belongsToMany(models.Rule, { 68 as: 'FavoriteRules', 69 through: 'users_and_favorite_rules', 70 }); 71 } 72 73 static async passwordMatchesHash(givenPassword: string, hash: string) { 74 return bcryptCompare(givenPassword, hash); 75 } 76 77 public getPermissions() { 78 return getPermissionsForRole(this.role); 79 } 80 } 81 82 /* Fields */ 83 User.init( 84 { 85 id: { 86 type: DataTypes.STRING, 87 primaryKey: true, 88 }, 89 orgId: { 90 type: DataTypes.STRING, 91 allowNull: false, 92 }, 93 email: { 94 type: DataTypes.STRING, 95 unique: true, 96 allowNull: false, 97 validate: { 98 isEmail: true, 99 notEmpty: true, 100 }, 101 }, 102 password: { 103 type: DataTypes.STRING, 104 unique: false, 105 }, 106 firstName: { 107 type: DataTypes.STRING, 108 unique: false, 109 allowNull: false, 110 validate: { 111 notEmpty: true, 112 }, 113 }, 114 lastName: { 115 type: DataTypes.STRING, 116 unique: false, 117 allowNull: false, 118 validate: { 119 notEmpty: true, 120 }, 121 }, 122 role: { 123 type: DataTypes.STRING, 124 unique: false, 125 defaultValue: UserRole.ADMIN, 126 validate: { 127 isIn: [Object.values(UserRole)], 128 }, 129 }, 130 // Has the user been approved by the admin as part of the org 131 approvedByAdmin: { 132 type: DataTypes.BOOLEAN, 133 defaultValue: false, 134 }, 135 // Has the user been rejected by the admin as part of the org 136 rejectedByAdmin: { 137 type: DataTypes.BOOLEAN, 138 defaultValue: false, 139 }, 140 loginMethods: { 141 type: DataTypes.ARRAY(DataTypes.ENUM('password', 'saml')), 142 defaultValue: ['password'], 143 allowNull: false, 144 }, 145 }, 146 { 147 sequelize, 148 modelName: 'user', 149 underscored: true, 150 }, 151 ); 152 153 return User; 154}; 155 156export default makeUserModel;