import * as Sequelize from 'sequelize'
import {
- AfterDelete,
+ AfterDestroy,
AfterUpdate,
AllowNull,
BeforeCreate,
import { hasUserRight, USER_ROLE_LABELS, UserRight } from '../../../shared'
import { User, UserRole } from '../../../shared/models/users'
import {
+ isUserAdminFlagsValid,
isUserAutoPlayVideoValid,
isUserBlockedReasonValid,
isUserBlockedValid,
isUserUsernameValid,
isUserVideoQuotaDailyValid,
isUserVideoQuotaValid,
+ isUserVideosHistoryEnabledValid,
isUserWebTorrentEnabledValid
} from '../../helpers/custom-validators/users'
import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto'
import { AccountModel } from './account'
import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type'
import { values } from 'lodash'
-import { NSFW_POLICY_TYPES } from '../../initializers'
+import { NSFW_POLICY_TYPES } from '../../initializers/constants'
import { clearCacheByUserId } from '../../lib/oauth-model'
+import { UserNotificationSettingModel } from './user-notification-setting'
+import { VideoModel } from '../video/video'
+import { ActorModel } from '../activitypub/actor'
+import { ActorFollowModel } from '../activitypub/actor-follow'
+import { VideoImportModel } from '../video/video-import'
+import { UserAdminFlag } from '../../../shared/models/users/user-flag.model'
enum ScopeNames {
WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL'
{
model: () => AccountModel,
required: true
+ },
+ {
+ model: () => UserNotificationSettingModel,
+ required: true
}
]
})
model: () => AccountModel,
required: true,
include: [ () => VideoChannelModel ]
+ },
+ {
+ model: () => UserNotificationSettingModel,
+ required: true
}
]
}
@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(UserAdminFlag.NONE)
+ @Is('UserAdminFlags', value => throwIfNotValid(value, isUserAdminFlagsValid, 'user admin flags'))
+ @Column
+ adminFlags?: UserAdminFlag
+
@AllowNull(false)
@Default(false)
@Is('UserBlocked', value => throwIfNotValid(value, isUserBlockedValid, 'blocked boolean'))
})
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'
}
@AfterUpdate
- @AfterDelete
+ @AfterDestroy
static removeTokenCache (instance: UserModel) {
return clearCacheByUserId(instance.id)
}
})
}
- static listEmailsWithRight (right: UserRight) {
+ static listWithRight (right: UserRight) {
const roles = Object.keys(USER_ROLE_LABELS)
.map(k => parseInt(k, 10) as UserRole)
.filter(role => hasUserRight(role, right))
const query = {
- attribute: [ 'email' ],
where: {
role: {
[Sequelize.Op.in]: roles
}
}
- return UserModel.unscoped()
- .findAll(query)
- .then(u => u.map(u => u.email))
+ return UserModel.findAll(query)
+ }
+
+ static listUserSubscribersOf (actorId: number) {
+ const query = {
+ include: [
+ {
+ model: UserNotificationSettingModel.unscoped(),
+ required: true
+ },
+ {
+ attributes: [ 'userId' ],
+ model: AccountModel.unscoped(),
+ required: true,
+ include: [
+ {
+ attributes: [ ],
+ model: ActorModel.unscoped(),
+ required: true,
+ where: {
+ serverId: null
+ },
+ include: [
+ {
+ attributes: [ ],
+ as: 'ActorFollowings',
+ model: ActorFollowModel.unscoped(),
+ required: true,
+ where: {
+ targetActorId: actorId
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+
+ return UserModel.unscoped().findAll(query)
+ }
+
+ static listByUsernames (usernames: string[]) {
+ const query = {
+ where: {
+ username: usernames
+ }
+ }
+
+ return UserModel.findAll(query)
}
static loadById (id: number) {
- return UserModel.findById(id)
+ return UserModel.findByPk(id)
}
static loadByUsername (username: string) {
return UserModel.findOne(query)
}
+ static loadByVideoId (videoId: number) {
+ const query = {
+ include: [
+ {
+ required: true,
+ attributes: [ 'id' ],
+ model: AccountModel.unscoped(),
+ include: [
+ {
+ required: true,
+ attributes: [ 'id' ],
+ model: VideoChannelModel.unscoped(),
+ include: [
+ {
+ required: true,
+ attributes: [ 'id' ],
+ model: VideoModel.unscoped(),
+ where: {
+ id: videoId
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+
+ return UserModel.findOne(query)
+ }
+
+ static loadByVideoImportId (videoImportId: number) {
+ const query = {
+ include: [
+ {
+ required: true,
+ attributes: [ 'id' ],
+ model: VideoImportModel.unscoped(),
+ where: {
+ id: videoImportId
+ }
+ }
+ ]
+ }
+
+ return UserModel.findOne(query)
+ }
+
+ static loadByChannelActorId (videoChannelActorId: number) {
+ const query = {
+ include: [
+ {
+ required: true,
+ attributes: [ 'id' ],
+ model: AccountModel.unscoped(),
+ include: [
+ {
+ required: true,
+ attributes: [ 'id' ],
+ model: VideoChannelModel.unscoped(),
+ where: {
+ actorId: videoChannelActorId
+ }
+ }
+ ]
+ }
+ ]
+ }
+
+ return UserModel.findOne(query)
+ }
+
+ static loadByAccountActorId (accountActorId: number) {
+ const query = {
+ include: [
+ {
+ required: true,
+ attributes: [ 'id' ],
+ model: AccountModel.unscoped(),
+ where: {
+ actorId: accountActorId
+ }
+ }
+ ]
+ }
+
+ return UserModel.findOne(query)
+ }
+
static getOriginalVideoFileTotalFromUser (user: UserModel) {
// Don't use sequelize because we need to use a sub query
const query = UserModel.generateUserQuotaBaseSQL()
return hasUserRight(this.role, right)
}
+ hasAdminFlag (flag: UserAdminFlag) {
+ return this.adminFlags & flag
+ }
+
isPasswordMatch (password: string) {
return comparePassword(password, this.password)
}
- toFormattedJSON (): User {
+ toFormattedJSON (parameters: { withAdminFlags?: boolean } = {}): User {
const videoQuotaUsed = this.get('videoQuotaUsed')
const videoQuotaUsedDaily = this.get('videoQuotaUsedDaily')
emailVerified: this.emailVerified,
nsfwPolicy: this.nsfwPolicy,
webTorrentEnabled: this.webTorrentEnabled,
+ videosHistoryEnabled: this.videosHistoryEnabled,
autoPlayVideo: this.autoPlayVideo,
role: this.role,
roleLabel: USER_ROLE_LABELS[ this.role ],
blocked: this.blocked,
blockedReason: this.blockedReason,
account: this.Account.toFormattedJSON(),
+ notificationSettings: this.NotificationSetting ? this.NotificationSetting.toFormattedJSON() : undefined,
videoChannels: [],
videoQuotaUsed: videoQuotaUsed !== undefined
? parseInt(videoQuotaUsed, 10)
: undefined
}
+ if (parameters.withAdminFlags) {
+ Object.assign(json, { adminFlags: this.adminFlags })
+ }
+
if (Array.isArray(this.Account.VideoChannels) === true) {
json.videoChannels = this.Account.VideoChannels
.map(c => c.toFormattedJSON())