+ {
+ model: () => UserNotificationSettingModel,
+ required: true
+ }
+ ]
+ }
+})
+@Table({
+ tableName: 'user',
+ indexes: [
+ {
+ fields: [ 'username' ],
+ unique: true
+ },
+ {
+ fields: [ 'email' ],
+ unique: true
+ }
+ ]
+})
+export class UserModel extends Model<UserModel> {
+
+ @AllowNull(false)
+ @Is('UserPassword', value => throwIfNotValid(value, isUserPasswordValid, 'user password'))
+ @Column
+ password: string
+
+ @AllowNull(false)
+ @Is('UserPassword', value => throwIfNotValid(value, isUserUsernameValid, 'user name'))
+ @Column
+ username: string
+
+ @AllowNull(false)
+ @IsEmail
+ @Column(DataType.STRING(400))
+ email: string
+
+ @AllowNull(true)
+ @Default(null)
+ @Is('UserEmailVerified', value => throwIfNotValid(value, isUserEmailVerifiedValid, 'email verified boolean'))
+ @Column
+ emailVerified: boolean
+
+ @AllowNull(false)
+ @Is('UserNSFWPolicy', value => throwIfNotValid(value, isUserNSFWPolicyValid, 'NSFW policy'))
+ @Column(DataType.ENUM(values(NSFW_POLICY_TYPES)))
+ nsfwPolicy: NSFWPolicyType
+
+ @AllowNull(false)
+ @Default(true)
+ @Is('UserWebTorrentEnabled', value => throwIfNotValid(value, isUserWebTorrentEnabledValid, 'WebTorrent enabled'))
+ @Column
+ webTorrentEnabled: boolean
+
+ @AllowNull(false)
+ @Default(true)
+ @Is('UserVideosHistoryEnabled', value => throwIfNotValid(value, isUserVideosHistoryEnabledValid, 'Videos history enabled'))
+ @Column
+ videosHistoryEnabled: boolean
+
+ @AllowNull(false)
+ @Default(true)
+ @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean'))
+ @Column
+ autoPlayVideo: boolean
+
+ @AllowNull(false)
+ @Default(false)
+ @Is('UserBlocked', value => throwIfNotValid(value, isUserBlockedValid, 'blocked boolean'))
+ @Column
+ blocked: boolean
+
+ @AllowNull(true)
+ @Default(null)
+ @Is('UserBlockedReason', value => throwIfNotValid(value, isUserBlockedReasonValid, 'blocked reason'))
+ @Column
+ blockedReason: string
+
+ @AllowNull(false)
+ @Is('UserRole', value => throwIfNotValid(value, isUserRoleValid, 'role'))
+ @Column
+ role: number
+
+ @AllowNull(false)
+ @Is('UserVideoQuota', value => throwIfNotValid(value, isUserVideoQuotaValid, 'video quota'))
+ @Column(DataType.BIGINT)
+ videoQuota: number
+
+ @AllowNull(false)
+ @Is('UserVideoQuotaDaily', value => throwIfNotValid(value, isUserVideoQuotaDailyValid, 'video quota daily'))
+ @Column(DataType.BIGINT)
+ videoQuotaDaily: number
+
+ @CreatedAt
+ createdAt: Date
+
+ @UpdatedAt
+ updatedAt: Date
+
+ @HasOne(() => AccountModel, {
+ foreignKey: 'userId',
+ onDelete: 'cascade',
+ hooks: true
+ })
+ Account: AccountModel
+
+ @HasOne(() => UserNotificationSettingModel, {
+ foreignKey: 'userId',
+ onDelete: 'cascade',
+ hooks: true
+ })
+ NotificationSetting: UserNotificationSettingModel
+
+ @HasMany(() => VideoImportModel, {
+ foreignKey: 'userId',
+ onDelete: 'cascade'
+ })
+ VideoImports: VideoImportModel[]
+
+ @HasMany(() => OAuthTokenModel, {
+ foreignKey: 'userId',
+ onDelete: 'cascade'
+ })
+ OAuthTokens: OAuthTokenModel[]
+
+ @BeforeCreate
+ @BeforeUpdate
+ static cryptPasswordIfNeeded (instance: UserModel) {
+ if (instance.changed('password')) {
+ return cryptPassword(instance.password)
+ .then(hash => {
+ instance.password = hash
+ return undefined
+ })
+ }
+ }
+
+ @AfterUpdate
+ @AfterDestroy
+ static removeTokenCache (instance: UserModel) {
+ return clearCacheByUserId(instance.id)
+ }
+
+ static countTotal () {
+ return this.count()
+ }
+
+ static listForApi (start: number, count: number, sort: string, search?: string) {
+ let where = undefined
+ if (search) {
+ where = {
+ [Sequelize.Op.or]: [
+ {
+ email: {
+ [Sequelize.Op.iLike]: '%' + search + '%'
+ }
+ },
+ {
+ username: {
+ [ Sequelize.Op.iLike ]: '%' + search + '%'
+ }