X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fmodels%2Faccount%2Fuser.ts;h=1165285ea318195200f818f4cf58af0b571eeb4a;hb=9c2e0dbfa9098675390e00ccb0fa49c51b3c6732;hp=84adad96e685409863c3474bec75f976f071f3fb;hpb=3fd3ab2d34d512b160a5e6084d7609be7b4f4452;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/models/account/user.ts b/server/models/account/user.ts index 84adad96e..1165285ea 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts @@ -3,30 +3,62 @@ import { AllowNull, BeforeCreate, BeforeUpdate, - Column, CreatedAt, + Column, + CreatedAt, DataType, Default, + DefaultScope, HasMany, HasOne, Is, IsEmail, Model, - Table, UpdatedAt + Scopes, + Table, + UpdatedAt } from 'sequelize-typescript' import { hasUserRight, USER_ROLE_LABELS, UserRight } from '../../../shared' +import { User, UserRole } from '../../../shared/models/users' import { - comparePassword, - cryptPassword -} from '../../helpers' -import { - isUserDisplayNSFWValid, isUserPasswordValid, isUserRoleValid, isUserUsernameValid, + isUserAutoPlayVideoValid, + isUserNSFWPolicyValid, + isUserPasswordValid, + isUserRoleValid, + isUserUsernameValid, isUserVideoQuotaValid } from '../../helpers/custom-validators/users' +import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto' import { OAuthTokenModel } from '../oauth/oauth-token' import { getSort, throwIfNotValid } from '../utils' import { VideoChannelModel } from '../video/video-channel' import { AccountModel } from './account' +import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type' +import { values } from 'lodash' +import { NSFW_POLICY_TYPES } from '../../initializers' + +enum ScopeNames { + WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL' +} +@DefaultScope({ + include: [ + { + model: () => AccountModel, + required: true + } + ] +}) +@Scopes({ + [ScopeNames.WITH_VIDEO_CHANNEL]: { + include: [ + { + model: () => AccountModel, + required: true, + include: [ () => VideoChannelModel ] + } + ] + } +}) @Table({ tableName: 'user', indexes: [ @@ -58,10 +90,15 @@ export class UserModel extends Model { email: string @AllowNull(false) - @Default(false) - @Is('UserDisplayNSFW', value => throwIfNotValid(value, isUserDisplayNSFWValid, 'display NSFW boolean')) + @Is('UserNSFWPolicy', value => throwIfNotValid(value, isUserNSFWPolicyValid, 'NSFW policy')) + @Column(DataType.ENUM(values(NSFW_POLICY_TYPES))) + nsfwPolicy: NSFWPolicyType + + @AllowNull(false) + @Default(true) + @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean')) @Column - displayNSFW: boolean + autoPlayVideo: boolean @AllowNull(false) @Is('UserRole', value => throwIfNotValid(value, isUserRoleValid, 'role')) @@ -81,7 +118,8 @@ export class UserModel extends Model { @HasOne(() => AccountModel, { foreignKey: 'userId', - onDelete: 'cascade' + onDelete: 'cascade', + hooks: true }) Account: AccountModel @@ -107,23 +145,11 @@ export class UserModel extends Model { return this.count() } - static getByUsername (username: string) { - const query = { - where: { - username: username - }, - include: [ { model: AccountModel, required: true } ] - } - - return UserModel.findOne(query) - } - static listForApi (start: number, count: number, sort: string) { const query = { offset: start, limit: count, - order: [ getSort(sort) ], - include: [ { model: AccountModel, required: true } ] + order: getSort(sort) } return UserModel.findAndCountAll(query) @@ -135,20 +161,36 @@ export class UserModel extends Model { }) } - static loadById (id: number) { - const options = { - include: [ { model: AccountModel, required: true } ] + static listEmailsWithRight (right: UserRight) { + const roles = Object.keys(USER_ROLE_LABELS) + .map(k => parseInt(k, 10) as UserRole) + .filter(role => hasUserRight(role, right)) + + console.log(roles) + + const query = { + attribute: [ 'email' ], + where: { + role: { + [Sequelize.Op.in]: roles + } + } } - return UserModel.findById(id, options) + return UserModel.unscoped() + .findAll(query) + .then(u => u.map(u => u.email)) + } + + static loadById (id: number) { + return UserModel.findById(id) } static loadByUsername (username: string) { const query = { where: { username - }, - include: [ { model: AccountModel, required: true } ] + } } return UserModel.findOne(query) @@ -158,32 +200,35 @@ export class UserModel extends Model { const query = { where: { username - }, - include: [ - { - model: AccountModel, - required: true, - include: [ VideoChannelModel ] - } - ] + } + } + + return UserModel.scope(ScopeNames.WITH_VIDEO_CHANNEL).findOne(query) + } + + static loadByEmail (email: string) { + const query = { + where: { + email + } } return UserModel.findOne(query) } - static loadByUsernameOrEmail (username: string, email: string) { + static loadByUsernameOrEmail (username: string, email?: string) { + if (!email) email = username + const query = { - include: [ { model: AccountModel, required: true } ], where: { [ Sequelize.Op.or ]: [ { username }, { email } ] } } - // FIXME: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18387 - return (UserModel as any).findOne(query) + return UserModel.findOne(query) } - private static getOriginalVideoFileTotalFromUser (user: UserModel) { + static getOriginalVideoFileTotalFromUser (user: UserModel) { // Don't use sequelize because we need to use a sub query const query = 'SELECT SUM("size") AS "total" FROM ' + '(SELECT MAX("videoFile"."size") AS "size" FROM "videoFile" ' + @@ -205,6 +250,14 @@ export class UserModel extends Model { }) } + static async getStats () { + const totalUsers = await UserModel.count() + + return { + totalUsers + } + } + hasRight (right: UserRight) { return hasUserRight(this.role, right) } @@ -213,21 +266,23 @@ export class UserModel extends Model { return comparePassword(password, this.password) } - toFormattedJSON () { + toFormattedJSON (): User { const json = { id: this.id, username: this.username, email: this.email, - displayNSFW: this.displayNSFW, + nsfwPolicy: this.nsfwPolicy, + autoPlayVideo: this.autoPlayVideo, role: this.role, roleLabel: USER_ROLE_LABELS[ this.role ], videoQuota: this.videoQuota, createdAt: this.createdAt, - account: this.Account.toFormattedJSON() + account: this.Account.toFormattedJSON(), + videoChannels: [] } if (Array.isArray(this.Account.VideoChannels) === true) { - json['videoChannels'] = this.Account.VideoChannels + json.videoChannels = this.Account.VideoChannels .map(c => c.toFormattedJSON()) .sort((v1, v2) => { if (v1.createdAt < v2.createdAt) return -1