mirror of https://github.com/Chocobozzz/PeerTube
Split user service
parent
cce70ae5ca
commit
d92d070c91
|
@ -10,6 +10,7 @@ import { SharedGlobalIconModule } from '@app/shared/shared-icons'
|
||||||
import { SharedMainModule } from '@app/shared/shared-main'
|
import { SharedMainModule } from '@app/shared/shared-main'
|
||||||
import { SharedModerationModule } from '@app/shared/shared-moderation'
|
import { SharedModerationModule } from '@app/shared/shared-moderation'
|
||||||
import { SharedTablesModule } from '@app/shared/shared-tables'
|
import { SharedTablesModule } from '@app/shared/shared-tables'
|
||||||
|
import { SharedUsersModule } from '@app/shared/shared-users'
|
||||||
import { SharedVideoCommentModule } from '@app/shared/shared-video-comment'
|
import { SharedVideoCommentModule } from '@app/shared/shared-video-comment'
|
||||||
import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature'
|
import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature'
|
||||||
import { AdminRoutingModule } from './admin-routing.module'
|
import { AdminRoutingModule } from './admin-routing.module'
|
||||||
|
@ -67,6 +68,7 @@ import { JobsComponent } from './system/jobs/jobs.component'
|
||||||
SharedCustomMarkupModule,
|
SharedCustomMarkupModule,
|
||||||
SharedVideoMiniatureModule,
|
SharedVideoMiniatureModule,
|
||||||
SharedTablesModule,
|
SharedTablesModule,
|
||||||
|
SharedUsersModule,
|
||||||
|
|
||||||
TableModule,
|
TableModule,
|
||||||
ChartModule
|
ChartModule
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit } from '@angular/core'
|
||||||
import { Router } from '@angular/router'
|
import { Router } from '@angular/router'
|
||||||
import { ConfigService } from '@app/+admin/config/shared/config.service'
|
import { ConfigService } from '@app/+admin/config/shared/config.service'
|
||||||
import { AuthService, Notifier, ScreenService, ServerService, UserService } from '@app/core'
|
import { AuthService, Notifier, ScreenService, ServerService } from '@app/core'
|
||||||
import {
|
import {
|
||||||
USER_CHANNEL_NAME_VALIDATOR,
|
USER_CHANNEL_NAME_VALIDATOR,
|
||||||
USER_EMAIL_VALIDATOR,
|
USER_EMAIL_VALIDATOR,
|
||||||
|
@ -13,6 +13,7 @@ import {
|
||||||
USER_VIDEO_QUOTA_VALIDATOR
|
USER_VIDEO_QUOTA_VALIDATOR
|
||||||
} from '@app/shared/form-validators/user-validators'
|
} from '@app/shared/form-validators/user-validators'
|
||||||
import { FormValidatorService } from '@app/shared/shared-forms'
|
import { FormValidatorService } from '@app/shared/shared-forms'
|
||||||
|
import { UserAdminService } from '@app/shared/shared-users'
|
||||||
import { UserCreate, UserRole } from '@shared/models'
|
import { UserCreate, UserRole } from '@shared/models'
|
||||||
import { UserEdit } from './user-edit'
|
import { UserEdit } from './user-edit'
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ export class UserCreateComponent extends UserEdit implements OnInit {
|
||||||
protected auth: AuthService,
|
protected auth: AuthService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private userService: UserService
|
private userAdminService: UserAdminService
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ export class UserCreateComponent extends UserEdit implements OnInit {
|
||||||
userCreate.videoQuota = parseInt(this.form.value['videoQuota'], 10)
|
userCreate.videoQuota = parseInt(this.form.value['videoQuota'], 10)
|
||||||
userCreate.videoQuotaDaily = parseInt(this.form.value['videoQuotaDaily'], 10)
|
userCreate.videoQuotaDaily = parseInt(this.form.value['videoQuotaDaily'], 10)
|
||||||
|
|
||||||
this.userService.addUser(userCreate)
|
this.userAdminService.addUser(userCreate)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success($localize`User ${userCreate.username} created.`)
|
this.notifier.success($localize`User ${userCreate.username} created.`)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { Component, Input, OnInit } from '@angular/core'
|
import { Component, Input, OnInit } from '@angular/core'
|
||||||
import { Notifier, UserService } from '@app/core'
|
import { Notifier } from '@app/core'
|
||||||
import { USER_PASSWORD_VALIDATOR } from '@app/shared/form-validators/user-validators'
|
import { USER_PASSWORD_VALIDATOR } from '@app/shared/form-validators/user-validators'
|
||||||
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
||||||
|
import { UserAdminService } from '@app/shared/shared-users'
|
||||||
import { UserUpdate } from '@shared/models'
|
import { UserUpdate } from '@shared/models'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -19,7 +20,7 @@ export class UserPasswordComponent extends FormReactive implements OnInit {
|
||||||
constructor (
|
constructor (
|
||||||
protected formValidatorService: FormValidatorService,
|
protected formValidatorService: FormValidatorService,
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private userService: UserService
|
private userAdminService: UserAdminService
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
@ -35,7 +36,7 @@ export class UserPasswordComponent extends FormReactive implements OnInit {
|
||||||
|
|
||||||
const userUpdate: UserUpdate = this.form.value
|
const userUpdate: UserUpdate = this.form.value
|
||||||
|
|
||||||
this.userService.updateUser(this.userId, userUpdate)
|
this.userAdminService.updateUser(this.userId, userUpdate)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => this.notifier.success($localize`Password changed for user ${this.username}.`),
|
next: () => this.notifier.success($localize`Password changed for user ${this.username}.`),
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
USER_VIDEO_QUOTA_VALIDATOR
|
USER_VIDEO_QUOTA_VALIDATOR
|
||||||
} from '@app/shared/form-validators/user-validators'
|
} from '@app/shared/form-validators/user-validators'
|
||||||
import { FormValidatorService } from '@app/shared/shared-forms'
|
import { FormValidatorService } from '@app/shared/shared-forms'
|
||||||
|
import { UserAdminService } from '@app/shared/shared-users'
|
||||||
import { User as UserType, UserAdminFlag, UserRole, UserUpdate } from '@shared/models'
|
import { User as UserType, UserAdminFlag, UserRole, UserUpdate } from '@shared/models'
|
||||||
import { UserEdit } from './user-edit'
|
import { UserEdit } from './user-edit'
|
||||||
|
|
||||||
|
@ -32,7 +33,8 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private userService: UserService
|
private userService: UserService,
|
||||||
|
private userAdminService: UserAdminService
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
|
@ -86,7 +88,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
|
||||||
|
|
||||||
if (userUpdate.pluginAuth === 'null') userUpdate.pluginAuth = null
|
if (userUpdate.pluginAuth === 'null') userUpdate.pluginAuth = null
|
||||||
|
|
||||||
this.userService.updateUser(this.user.id, userUpdate)
|
this.userAdminService.updateUser(this.user.id, userUpdate)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success($localize`User ${this.user.username} updated.`)
|
this.notifier.success($localize`User ${this.user.username} updated.`)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { SortMeta } from 'primeng/api'
|
import { SortMeta } from 'primeng/api'
|
||||||
import { Component, OnInit, ViewChild } from '@angular/core'
|
import { Component, OnInit, ViewChild } from '@angular/core'
|
||||||
import { ActivatedRoute, Router } from '@angular/router'
|
import { ActivatedRoute, Router } from '@angular/router'
|
||||||
import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService, UserService } from '@app/core'
|
import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService } from '@app/core'
|
||||||
import { AdvancedInputFilter } from '@app/shared/shared-forms'
|
import { AdvancedInputFilter } from '@app/shared/shared-forms'
|
||||||
import { DropdownAction } from '@app/shared/shared-main'
|
import { DropdownAction } from '@app/shared/shared-main'
|
||||||
import { UserBanModalComponent } from '@app/shared/shared-moderation'
|
import { UserBanModalComponent } from '@app/shared/shared-moderation'
|
||||||
|
import { UserAdminService } from '@app/shared/shared-users'
|
||||||
import { User, UserRole } from '@shared/models'
|
import { User, UserRole } from '@shared/models'
|
||||||
|
|
||||||
type UserForList = User & {
|
type UserForList = User & {
|
||||||
|
@ -57,7 +58,7 @@ export class UserListComponent extends RestTable implements OnInit {
|
||||||
private confirmService: ConfirmService,
|
private confirmService: ConfirmService,
|
||||||
private serverService: ServerService,
|
private serverService: ServerService,
|
||||||
private auth: AuthService,
|
private auth: AuthService,
|
||||||
private userService: UserService
|
private userAdminService: UserAdminService
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
@ -177,7 +178,7 @@ export class UserListComponent extends RestTable implements OnInit {
|
||||||
const res = await this.confirmService.confirm($localize`Do you really want to unban ${users.length} users?`, $localize`Unban`)
|
const res = await this.confirmService.confirm($localize`Do you really want to unban ${users.length} users?`, $localize`Unban`)
|
||||||
if (res === false) return
|
if (res === false) return
|
||||||
|
|
||||||
this.userService.unbanUsers(users)
|
this.userAdminService.unbanUsers(users)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success($localize`${users.length} users unbanned.`)
|
this.notifier.success($localize`${users.length} users unbanned.`)
|
||||||
|
@ -200,7 +201,7 @@ export class UserListComponent extends RestTable implements OnInit {
|
||||||
const res = await this.confirmService.confirm(message, $localize`Delete`)
|
const res = await this.confirmService.confirm(message, $localize`Delete`)
|
||||||
if (res === false) return
|
if (res === false) return
|
||||||
|
|
||||||
this.userService.removeUser(users)
|
this.userAdminService.removeUser(users)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success($localize`${users.length} users deleted.`)
|
this.notifier.success($localize`${users.length} users deleted.`)
|
||||||
|
@ -212,7 +213,7 @@ export class UserListComponent extends RestTable implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
setEmailsAsVerified (users: User[]) {
|
setEmailsAsVerified (users: User[]) {
|
||||||
this.userService.updateUsers(users, { emailVerified: true })
|
this.userAdminService.updateUsers(users, { emailVerified: true })
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success($localize`${users.length} users email set as verified.`)
|
this.notifier.success($localize`${users.length} users email set as verified.`)
|
||||||
|
@ -230,7 +231,7 @@ export class UserListComponent extends RestTable implements OnInit {
|
||||||
protected reloadData () {
|
protected reloadData () {
|
||||||
this.selectedUsers = []
|
this.selectedUsers = []
|
||||||
|
|
||||||
this.userService.getUsers({
|
this.userAdminService.getUsers({
|
||||||
pagination: this.pagination,
|
pagination: this.pagination,
|
||||||
sort: this.sort,
|
sort: this.sort,
|
||||||
search: this.search
|
search: this.search
|
||||||
|
|
|
@ -2,9 +2,9 @@ import { concat, of } from 'rxjs'
|
||||||
import { pairwise } from 'rxjs/operators'
|
import { pairwise } from 'rxjs/operators'
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
||||||
import { FormGroup } from '@angular/forms'
|
import { FormGroup } from '@angular/forms'
|
||||||
import { UserService } from '@app/core'
|
|
||||||
import { VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR, VIDEO_CHANNEL_NAME_VALIDATOR } from '@app/shared/form-validators/video-channel-validators'
|
import { VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR, VIDEO_CHANNEL_NAME_VALIDATOR } from '@app/shared/form-validators/video-channel-validators'
|
||||||
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
||||||
|
import { UserSignupService } from '@app/shared/shared-users'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-register-step-channel',
|
selector: 'my-register-step-channel',
|
||||||
|
@ -17,7 +17,7 @@ export class RegisterStepChannelComponent extends FormReactive implements OnInit
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
protected formValidatorService: FormValidatorService,
|
protected formValidatorService: FormValidatorService,
|
||||||
private userService: UserService
|
private userSignupService: UserSignupService
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ export class RegisterStepChannelComponent extends FormReactive implements OnInit
|
||||||
private onDisplayNameChange (oldDisplayName: string, newDisplayName: string) {
|
private onDisplayNameChange (oldDisplayName: string, newDisplayName: string) {
|
||||||
const name = this.form.value['name'] || ''
|
const name = this.form.value['name'] || ''
|
||||||
|
|
||||||
const newName = this.userService.getNewUsername(oldDisplayName, newDisplayName, name)
|
const newName = this.userSignupService.getNewUsername(oldDisplayName, newDisplayName, name)
|
||||||
this.form.patchValue({ name: newName })
|
this.form.patchValue({ name: newName })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { concat, of } from 'rxjs'
|
||||||
import { pairwise } from 'rxjs/operators'
|
import { pairwise } from 'rxjs/operators'
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
|
||||||
import { FormGroup } from '@angular/forms'
|
import { FormGroup } from '@angular/forms'
|
||||||
import { UserService } from '@app/core'
|
|
||||||
import {
|
import {
|
||||||
USER_DISPLAY_NAME_REQUIRED_VALIDATOR,
|
USER_DISPLAY_NAME_REQUIRED_VALIDATOR,
|
||||||
USER_EMAIL_VALIDATOR,
|
USER_EMAIL_VALIDATOR,
|
||||||
|
@ -10,6 +9,7 @@ import {
|
||||||
USER_USERNAME_VALIDATOR
|
USER_USERNAME_VALIDATOR
|
||||||
} from '@app/shared/form-validators/user-validators'
|
} from '@app/shared/form-validators/user-validators'
|
||||||
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
||||||
|
import { UserSignupService } from '@app/shared/shared-users'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-register-step-user',
|
selector: 'my-register-step-user',
|
||||||
|
@ -23,7 +23,7 @@ export class RegisterStepUserComponent extends FormReactive implements OnInit {
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
protected formValidatorService: FormValidatorService,
|
protected formValidatorService: FormValidatorService,
|
||||||
private userService: UserService
|
private userSignupService: UserSignupService
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ export class RegisterStepUserComponent extends FormReactive implements OnInit {
|
||||||
private onDisplayNameChange (oldDisplayName: string, newDisplayName: string) {
|
private onDisplayNameChange (oldDisplayName: string, newDisplayName: string) {
|
||||||
const username = this.form.value['username'] || ''
|
const username = this.form.value['username'] || ''
|
||||||
|
|
||||||
const newUsername = this.userService.getNewUsername(oldDisplayName, newDisplayName, username)
|
const newUsername = this.userSignupService.getNewUsername(oldDisplayName, newDisplayName, username)
|
||||||
this.form.patchValue({ username: newUsername })
|
this.form.patchValue({ username: newUsername })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit } from '@angular/core'
|
||||||
import { FormGroup } from '@angular/forms'
|
import { FormGroup } from '@angular/forms'
|
||||||
import { ActivatedRoute } from '@angular/router'
|
import { ActivatedRoute } from '@angular/router'
|
||||||
import { AuthService, UserService } from '@app/core'
|
import { AuthService } from '@app/core'
|
||||||
import { HooksService } from '@app/core/plugins/hooks.service'
|
import { HooksService } from '@app/core/plugins/hooks.service'
|
||||||
|
import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance'
|
||||||
|
import { UserSignupService } from '@app/shared/shared-users'
|
||||||
import { NgbAccordion } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbAccordion } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { UserRegister } from '@shared/models'
|
import { UserRegister } from '@shared/models'
|
||||||
import { ServerConfig } from '@shared/models/server'
|
import { ServerConfig } from '@shared/models/server'
|
||||||
import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance'
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-register',
|
selector: 'my-register',
|
||||||
|
@ -49,7 +50,7 @@ export class RegisterComponent implements OnInit {
|
||||||
constructor (
|
constructor (
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private userService: UserService,
|
private userSignupService: UserSignupService,
|
||||||
private hooks: HooksService
|
private hooks: HooksService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ export class RegisterComponent implements OnInit {
|
||||||
'filter:api.signup.registration.create.params'
|
'filter:api.signup.registration.create.params'
|
||||||
)
|
)
|
||||||
|
|
||||||
this.userService.signup(body).subscribe({
|
this.userSignupService.signup(body).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.signupDone = true
|
this.signupDone = true
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { CdkStepperModule } from '@angular/cdk/stepper'
|
import { CdkStepperModule } from '@angular/cdk/stepper'
|
||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { SignupSharedModule } from '@app/+signup/shared/signup-shared.module'
|
import { SharedSignupModule } from '@app/+signup/shared/shared-signup.module'
|
||||||
import { SharedInstanceModule } from '@app/shared/shared-instance'
|
import { SharedInstanceModule } from '@app/shared/shared-instance'
|
||||||
import { CustomStepperComponent } from './custom-stepper.component'
|
import { CustomStepperComponent } from './custom-stepper.component'
|
||||||
import { RegisterRoutingModule } from './register-routing.module'
|
import { RegisterRoutingModule } from './register-routing.module'
|
||||||
|
@ -15,7 +15,7 @@ import { RegisterComponent } from './register.component'
|
||||||
|
|
||||||
CdkStepperModule,
|
CdkStepperModule,
|
||||||
|
|
||||||
SignupSharedModule,
|
SharedSignupModule,
|
||||||
|
|
||||||
SharedInstanceModule
|
SharedInstanceModule
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit } from '@angular/core'
|
||||||
import { Notifier, RedirectService, ServerService, UserService } from '@app/core'
|
import { Notifier, RedirectService, ServerService } from '@app/core'
|
||||||
import { USER_EMAIL_VALIDATOR } from '@app/shared/form-validators/user-validators'
|
import { USER_EMAIL_VALIDATOR } from '@app/shared/form-validators/user-validators'
|
||||||
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
||||||
|
import { UserSignupService } from '@app/shared/shared-users'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-verify-account-ask-send-email',
|
selector: 'my-verify-account-ask-send-email',
|
||||||
|
@ -14,7 +15,7 @@ export class VerifyAccountAskSendEmailComponent extends FormReactive implements
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
protected formValidatorService: FormValidatorService,
|
protected formValidatorService: FormValidatorService,
|
||||||
private userService: UserService,
|
private userSignupService: UserSignupService,
|
||||||
private serverService: ServerService,
|
private serverService: ServerService,
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private redirectService: RedirectService
|
private redirectService: RedirectService
|
||||||
|
@ -33,7 +34,7 @@ export class VerifyAccountAskSendEmailComponent extends FormReactive implements
|
||||||
|
|
||||||
askSendVerifyEmail () {
|
askSendVerifyEmail () {
|
||||||
const email = this.form.value['verify-email-email']
|
const email = this.form.value['verify-email-email']
|
||||||
this.userService.askSendVerifyEmail(email)
|
this.userSignupService.askSendVerifyEmail(email)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success($localize`An email with verification link will be sent to ${email}.`)
|
this.notifier.success($localize`An email with verification link will be sent to ${email}.`)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Component, OnInit } from '@angular/core'
|
import { Component, OnInit } from '@angular/core'
|
||||||
import { ActivatedRoute } from '@angular/router'
|
import { ActivatedRoute } from '@angular/router'
|
||||||
import { AuthService, Notifier, UserService } from '@app/core'
|
import { AuthService, Notifier } from '@app/core'
|
||||||
|
import { UserSignupService } from '@app/shared/shared-users'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-verify-account-email',
|
selector: 'my-verify-account-email',
|
||||||
|
@ -16,7 +17,7 @@ export class VerifyAccountEmailComponent implements OnInit {
|
||||||
private verificationString: string
|
private verificationString: string
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private userService: UserService,
|
private userSignupService: UserSignupService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private route: ActivatedRoute
|
private route: ActivatedRoute
|
||||||
|
@ -37,7 +38,7 @@ export class VerifyAccountEmailComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyEmail () {
|
verifyEmail () {
|
||||||
this.userService.verifyEmail(this.userId, this.verificationString, this.isPendingEmail)
|
this.userSignupService.verifyEmail(this.userId, this.verificationString, this.isPendingEmail)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
if (this.authService.isLoggedIn()) {
|
if (this.authService.isLoggedIn()) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { SignupSharedModule } from '../shared/signup-shared.module'
|
import { SharedSignupModule } from '../shared/shared-signup.module'
|
||||||
import { VerifyAccountAskSendEmailComponent } from './verify-account-ask-send-email/verify-account-ask-send-email.component'
|
import { VerifyAccountAskSendEmailComponent } from './verify-account-ask-send-email/verify-account-ask-send-email.component'
|
||||||
import { VerifyAccountEmailComponent } from './verify-account-email/verify-account-email.component'
|
import { VerifyAccountEmailComponent } from './verify-account-email/verify-account-email.component'
|
||||||
import { VerifyAccountRoutingModule } from './verify-account-routing.module'
|
import { VerifyAccountRoutingModule } from './verify-account-routing.module'
|
||||||
|
@ -8,7 +8,7 @@ import { VerifyAccountRoutingModule } from './verify-account-routing.module'
|
||||||
imports: [
|
imports: [
|
||||||
VerifyAccountRoutingModule,
|
VerifyAccountRoutingModule,
|
||||||
|
|
||||||
SignupSharedModule
|
SharedSignupModule
|
||||||
],
|
],
|
||||||
|
|
||||||
declarations: [
|
declarations: [
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { SharedMainModule } from '@app/shared/shared-main'
|
|
||||||
import { SignupSuccessComponent } from './signup-success.component'
|
|
||||||
import { SharedFormModule } from '@app/shared/shared-forms'
|
import { SharedFormModule } from '@app/shared/shared-forms'
|
||||||
import { SharedGlobalIconModule } from '@app/shared/shared-icons'
|
import { SharedGlobalIconModule } from '@app/shared/shared-icons'
|
||||||
|
import { SharedMainModule } from '@app/shared/shared-main'
|
||||||
|
import { SharedUsersModule } from '@app/shared/shared-users'
|
||||||
|
import { SignupSuccessComponent } from './signup-success.component'
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
SharedMainModule,
|
SharedMainModule,
|
||||||
SharedFormModule,
|
SharedFormModule,
|
||||||
SharedGlobalIconModule
|
SharedGlobalIconModule,
|
||||||
|
SharedUsersModule
|
||||||
],
|
],
|
||||||
|
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -26,4 +28,4 @@ import { SharedGlobalIconModule } from '@app/shared/shared-icons'
|
||||||
providers: [
|
providers: [
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SignupSharedModule { }
|
export class SharedSignupModule { }
|
|
@ -1,24 +1,12 @@
|
||||||
import { SortMeta } from 'primeng/api'
|
import { Observable, of } from 'rxjs'
|
||||||
import { from, Observable, of } from 'rxjs'
|
import { catchError, first, map, shareReplay } from 'rxjs/operators'
|
||||||
import { catchError, concatMap, first, map, shareReplay, tap, toArray } from 'rxjs/operators'
|
|
||||||
import { HttpClient, HttpParams } from '@angular/common/http'
|
import { HttpClient, HttpParams } from '@angular/common/http'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { AuthService } from '@app/core/auth'
|
import { AuthService } from '@app/core/auth'
|
||||||
import { getBytes } from '@root-helpers/bytes'
|
import { ActorImage, User as UserServerModel, UserUpdateMe, UserVideoQuota } from '@shared/models'
|
||||||
import {
|
|
||||||
ActorImage,
|
|
||||||
ResultList,
|
|
||||||
User as UserServerModel,
|
|
||||||
UserCreate,
|
|
||||||
UserRegister,
|
|
||||||
UserRole,
|
|
||||||
UserUpdate,
|
|
||||||
UserUpdateMe,
|
|
||||||
UserVideoQuota
|
|
||||||
} from '@shared/models'
|
|
||||||
import { environment } from '../../../environments/environment'
|
import { environment } from '../../../environments/environment'
|
||||||
import { RestExtractor, RestPagination, RestService } from '../rest'
|
import { RestExtractor } from '../rest'
|
||||||
import { UserLocalStorageService } from './'
|
import { UserLocalStorageService } from './user-local-storage.service'
|
||||||
import { User } from './user.model'
|
import { User } from './user.model'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -26,21 +14,71 @@ export class UserService {
|
||||||
static BASE_USERS_URL = environment.apiUrl + '/api/v1/users/'
|
static BASE_USERS_URL = environment.apiUrl + '/api/v1/users/'
|
||||||
|
|
||||||
private userCache: { [ id: number ]: Observable<UserServerModel> } = {}
|
private userCache: { [ id: number ]: Observable<UserServerModel> } = {}
|
||||||
|
|
||||||
private signupInThisSession = false
|
private signupInThisSession = false
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private authHttp: HttpClient,
|
private authHttp: HttpClient,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private restExtractor: RestExtractor,
|
private restExtractor: RestExtractor,
|
||||||
private restService: RestService,
|
|
||||||
private userLocalStorageService: UserLocalStorageService
|
private userLocalStorageService: UserLocalStorageService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
getUserWithCache (userId: number) {
|
||||||
|
if (!this.userCache[userId]) {
|
||||||
|
this.userCache[userId] = this.getUser(userId).pipe(shareReplay())
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.userCache[userId]
|
||||||
|
}
|
||||||
|
|
||||||
|
getUser (userId: number, withStats = false) {
|
||||||
|
const params = new HttpParams().append('withStats', withStats + '')
|
||||||
|
|
||||||
|
return this.authHttp.get<UserServerModel>(UserService.BASE_USERS_URL + userId, { params })
|
||||||
|
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
setSignupInThisSession (value: boolean) {
|
||||||
|
this.signupInThisSession = value
|
||||||
|
}
|
||||||
|
|
||||||
hasSignupInThisSession () {
|
hasSignupInThisSession () {
|
||||||
return this.signupInThisSession
|
return this.signupInThisSession
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
updateMyAnonymousProfile (profile: UserUpdateMe) {
|
||||||
|
this.userLocalStorageService.setUserInfo(profile)
|
||||||
|
}
|
||||||
|
|
||||||
|
listenAnonymousUpdate () {
|
||||||
|
return this.userLocalStorageService.listenUserInfoChange()
|
||||||
|
.pipe(map(() => this.getAnonymousUser()))
|
||||||
|
}
|
||||||
|
|
||||||
|
getAnonymousUser () {
|
||||||
|
return new User(this.userLocalStorageService.getUserInfo())
|
||||||
|
}
|
||||||
|
|
||||||
|
getAnonymousOrLoggedUser () {
|
||||||
|
if (!this.authService.isLoggedIn()) {
|
||||||
|
return of(this.getAnonymousUser())
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.authService.userInformationLoaded
|
||||||
|
.pipe(
|
||||||
|
first(),
|
||||||
|
map(() => this.authService.getUser())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
changePassword (currentPassword: string, newPassword: string) {
|
changePassword (currentPassword: string, newPassword: string) {
|
||||||
const url = UserService.BASE_USERS_URL + 'me'
|
const url = UserService.BASE_USERS_URL + 'me'
|
||||||
const body: UserUpdateMe = {
|
const body: UserUpdateMe = {
|
||||||
|
@ -63,23 +101,6 @@ export class UserService {
|
||||||
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
updateMyAnonymousProfile (profile: UserUpdateMe) {
|
|
||||||
this.userLocalStorageService.setUserInfo(profile)
|
|
||||||
}
|
|
||||||
|
|
||||||
listenAnonymousUpdate () {
|
|
||||||
return this.userLocalStorageService.listenUserInfoChange()
|
|
||||||
.pipe(map(() => this.getAnonymousUser()))
|
|
||||||
}
|
|
||||||
|
|
||||||
getAnonymousUser () {
|
|
||||||
return new User(this.userLocalStorageService.getUserInfo())
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
updateMyProfile (profile: UserUpdateMe) {
|
updateMyProfile (profile: UserUpdateMe) {
|
||||||
const url = UserService.BASE_USERS_URL + 'me'
|
const url = UserService.BASE_USERS_URL + 'me'
|
||||||
|
|
||||||
|
@ -108,14 +129,6 @@ export class UserService {
|
||||||
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
signup (userCreate: UserRegister) {
|
|
||||||
return this.authHttp.post(UserService.BASE_USERS_URL + 'register', userCreate)
|
|
||||||
.pipe(
|
|
||||||
tap(() => this.signupInThisSession = true),
|
|
||||||
catchError(err => this.restExtractor.handleError(err))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
getMyVideoQuotaUsed () {
|
getMyVideoQuotaUsed () {
|
||||||
const url = UserService.BASE_USERS_URL + 'me/video-quota-used'
|
const url = UserService.BASE_USERS_URL + 'me/video-quota-used'
|
||||||
|
|
||||||
|
@ -141,24 +154,6 @@ export class UserService {
|
||||||
.pipe(catchError(res => this.restExtractor.handleError(res)))
|
.pipe(catchError(res => this.restExtractor.handleError(res)))
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyEmail (userId: number, verificationString: string, isPendingEmail: boolean) {
|
|
||||||
const url = `${UserService.BASE_USERS_URL}/${userId}/verify-email`
|
|
||||||
const body = {
|
|
||||||
verificationString,
|
|
||||||
isPendingEmail
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.authHttp.post(url, body)
|
|
||||||
.pipe(catchError(res => this.restExtractor.handleError(res)))
|
|
||||||
}
|
|
||||||
|
|
||||||
askSendVerifyEmail (email: string) {
|
|
||||||
const url = UserService.BASE_USERS_URL + '/ask-send-verify-email'
|
|
||||||
|
|
||||||
return this.authHttp.post(url, { email })
|
|
||||||
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
autocomplete (search: string): Observable<string[]> {
|
autocomplete (search: string): Observable<string[]> {
|
||||||
const url = UserService.BASE_USERS_URL + 'autocomplete'
|
const url = UserService.BASE_USERS_URL + 'autocomplete'
|
||||||
const params = new HttpParams().append('search', search)
|
const params = new HttpParams().append('search', search)
|
||||||
|
@ -167,169 +162,4 @@ export class UserService {
|
||||||
.get<string[]>(url, { params })
|
.get<string[]>(url, { params })
|
||||||
.pipe(catchError(res => this.restExtractor.handleError(res)))
|
.pipe(catchError(res => this.restExtractor.handleError(res)))
|
||||||
}
|
}
|
||||||
|
|
||||||
getNewUsername (oldDisplayName: string, newDisplayName: string, currentUsername: string) {
|
|
||||||
// Don't update display name, the user seems to have changed it
|
|
||||||
if (this.displayNameToUsername(oldDisplayName) !== currentUsername) return currentUsername
|
|
||||||
|
|
||||||
return this.displayNameToUsername(newDisplayName)
|
|
||||||
}
|
|
||||||
|
|
||||||
displayNameToUsername (displayName: string) {
|
|
||||||
if (!displayName) return ''
|
|
||||||
|
|
||||||
return displayName
|
|
||||||
.toLowerCase()
|
|
||||||
.replace(/\s/g, '_')
|
|
||||||
.replace(/[^a-z0-9_.]/g, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ###### Admin methods ###### */
|
|
||||||
|
|
||||||
addUser (userCreate: UserCreate) {
|
|
||||||
return this.authHttp.post(UserService.BASE_USERS_URL, userCreate)
|
|
||||||
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
updateUser (userId: number, userUpdate: UserUpdate) {
|
|
||||||
return this.authHttp.put(UserService.BASE_USERS_URL + userId, userUpdate)
|
|
||||||
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
updateUsers (users: UserServerModel[], userUpdate: UserUpdate) {
|
|
||||||
return from(users)
|
|
||||||
.pipe(
|
|
||||||
concatMap(u => this.authHttp.put(UserService.BASE_USERS_URL + u.id, userUpdate)),
|
|
||||||
toArray(),
|
|
||||||
catchError(err => this.restExtractor.handleError(err))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
getUserWithCache (userId: number) {
|
|
||||||
if (!this.userCache[userId]) {
|
|
||||||
this.userCache[userId] = this.getUser(userId).pipe(shareReplay())
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.userCache[userId]
|
|
||||||
}
|
|
||||||
|
|
||||||
getUser (userId: number, withStats = false) {
|
|
||||||
const params = new HttpParams().append('withStats', withStats + '')
|
|
||||||
return this.authHttp.get<UserServerModel>(UserService.BASE_USERS_URL + userId, { params })
|
|
||||||
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
getUsers (parameters: {
|
|
||||||
pagination: RestPagination
|
|
||||||
sort: SortMeta
|
|
||||||
search?: string
|
|
||||||
}): Observable<ResultList<UserServerModel>> {
|
|
||||||
const { pagination, sort, search } = parameters
|
|
||||||
|
|
||||||
let params = new HttpParams()
|
|
||||||
params = this.restService.addRestGetParams(params, pagination, sort)
|
|
||||||
|
|
||||||
if (search) {
|
|
||||||
const filters = this.restService.parseQueryStringFilter(search, {
|
|
||||||
blocked: {
|
|
||||||
prefix: 'banned:',
|
|
||||||
isBoolean: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
params = this.restService.addObjectParams(params, filters)
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.authHttp.get<ResultList<UserServerModel>>(UserService.BASE_USERS_URL, { params })
|
|
||||||
.pipe(
|
|
||||||
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
|
||||||
map(res => this.restExtractor.applyToResultListData(res, this.formatUser.bind(this))),
|
|
||||||
catchError(err => this.restExtractor.handleError(err))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
removeUser (usersArg: UserServerModel | UserServerModel[]) {
|
|
||||||
const users = Array.isArray(usersArg) ? usersArg : [ usersArg ]
|
|
||||||
|
|
||||||
return from(users)
|
|
||||||
.pipe(
|
|
||||||
concatMap(u => this.authHttp.delete(UserService.BASE_USERS_URL + u.id)),
|
|
||||||
toArray(),
|
|
||||||
catchError(err => this.restExtractor.handleError(err))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
banUsers (usersArg: UserServerModel | UserServerModel[], reason?: string) {
|
|
||||||
const body = reason ? { reason } : {}
|
|
||||||
const users = Array.isArray(usersArg) ? usersArg : [ usersArg ]
|
|
||||||
|
|
||||||
return from(users)
|
|
||||||
.pipe(
|
|
||||||
concatMap(u => this.authHttp.post(UserService.BASE_USERS_URL + u.id + '/block', body)),
|
|
||||||
toArray(),
|
|
||||||
catchError(err => this.restExtractor.handleError(err))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
unbanUsers (usersArg: UserServerModel | UserServerModel[]) {
|
|
||||||
const users = Array.isArray(usersArg) ? usersArg : [ usersArg ]
|
|
||||||
|
|
||||||
return from(users)
|
|
||||||
.pipe(
|
|
||||||
concatMap(u => this.authHttp.post(UserService.BASE_USERS_URL + u.id + '/unblock', {})),
|
|
||||||
toArray(),
|
|
||||||
catchError(err => this.restExtractor.handleError(err))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
getAnonymousOrLoggedUser () {
|
|
||||||
if (!this.authService.isLoggedIn()) {
|
|
||||||
return of(this.getAnonymousUser())
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.authService.userInformationLoaded
|
|
||||||
.pipe(
|
|
||||||
first(),
|
|
||||||
map(() => this.authService.getUser())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private formatUser (user: UserServerModel) {
|
|
||||||
let videoQuota
|
|
||||||
if (user.videoQuota === -1) {
|
|
||||||
videoQuota = '∞'
|
|
||||||
} else {
|
|
||||||
videoQuota = getBytes(user.videoQuota, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
const videoQuotaUsed = getBytes(user.videoQuotaUsed, 0)
|
|
||||||
|
|
||||||
let videoQuotaDaily: string
|
|
||||||
let videoQuotaUsedDaily: string
|
|
||||||
if (user.videoQuotaDaily === -1) {
|
|
||||||
videoQuotaDaily = '∞'
|
|
||||||
videoQuotaUsedDaily = getBytes(0, 0) + ''
|
|
||||||
} else {
|
|
||||||
videoQuotaDaily = getBytes(user.videoQuotaDaily, 0) + ''
|
|
||||||
videoQuotaUsedDaily = getBytes(user.videoQuotaUsedDaily || 0, 0) + ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleLabels: { [ id in UserRole ]: string } = {
|
|
||||||
[UserRole.USER]: $localize`User`,
|
|
||||||
[UserRole.ADMINISTRATOR]: $localize`Administrator`,
|
|
||||||
[UserRole.MODERATOR]: $localize`Moderator`
|
|
||||||
}
|
|
||||||
|
|
||||||
return Object.assign(user, {
|
|
||||||
roleLabel: roleLabels[user.role],
|
|
||||||
videoQuota,
|
|
||||||
videoQuotaUsed,
|
|
||||||
rawVideoQuota: user.videoQuota,
|
|
||||||
rawVideoQuotaUsed: user.videoQuotaUsed,
|
|
||||||
videoQuotaDaily,
|
|
||||||
videoQuotaUsedDaily,
|
|
||||||
rawVideoQuotaDaily: user.videoQuotaDaily,
|
|
||||||
rawVideoQuotaUsedDaily: user.videoQuotaUsedDaily
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
|
|
||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
|
import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module'
|
||||||
import { SharedFormModule } from '../shared-forms/shared-form.module'
|
import { SharedFormModule } from '../shared-forms/shared-form.module'
|
||||||
import { SharedGlobalIconModule } from '../shared-icons'
|
import { SharedGlobalIconModule } from '../shared-icons'
|
||||||
import { SharedMainModule } from '../shared-main/shared-main.module'
|
import { SharedMainModule } from '../shared-main/shared-main.module'
|
||||||
|
import { SharedUsersModule } from '../shared-users'
|
||||||
import { SharedVideoCommentModule } from '../shared-video-comment'
|
import { SharedVideoCommentModule } from '../shared-video-comment'
|
||||||
import { AbuseService } from './abuse.service'
|
import { AbuseService } from './abuse.service'
|
||||||
|
import { AccountBlockBadgesComponent } from './account-block-badges.component'
|
||||||
import { BatchDomainsModalComponent } from './batch-domains-modal.component'
|
import { BatchDomainsModalComponent } from './batch-domains-modal.component'
|
||||||
import { BlocklistService } from './blocklist.service'
|
import { BlocklistService } from './blocklist.service'
|
||||||
import { BulkService } from './bulk.service'
|
import { BulkService } from './bulk.service'
|
||||||
|
@ -13,8 +16,6 @@ import { UserBanModalComponent } from './user-ban-modal.component'
|
||||||
import { UserModerationDropdownComponent } from './user-moderation-dropdown.component'
|
import { UserModerationDropdownComponent } from './user-moderation-dropdown.component'
|
||||||
import { VideoBlockComponent } from './video-block.component'
|
import { VideoBlockComponent } from './video-block.component'
|
||||||
import { VideoBlockService } from './video-block.service'
|
import { VideoBlockService } from './video-block.service'
|
||||||
import { AccountBlockBadgesComponent } from './account-block-badges.component'
|
|
||||||
import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module'
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -22,7 +23,8 @@ import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image
|
||||||
SharedFormModule,
|
SharedFormModule,
|
||||||
SharedGlobalIconModule,
|
SharedGlobalIconModule,
|
||||||
SharedVideoCommentModule,
|
SharedVideoCommentModule,
|
||||||
SharedActorImageModule
|
SharedActorImageModule,
|
||||||
|
SharedUsersModule
|
||||||
],
|
],
|
||||||
|
|
||||||
declarations: [
|
declarations: [
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
|
import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
|
||||||
import { Notifier, UserService } from '@app/core'
|
import { Notifier } from '@app/core'
|
||||||
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
|
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
|
||||||
import { User } from '@shared/models'
|
import { User } from '@shared/models'
|
||||||
import { USER_BAN_REASON_VALIDATOR } from '../form-validators/user-validators'
|
import { USER_BAN_REASON_VALIDATOR } from '../form-validators/user-validators'
|
||||||
|
import { UserAdminService } from '../shared-users'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-user-ban-modal',
|
selector: 'my-user-ban-modal',
|
||||||
|
@ -23,7 +24,7 @@ export class UserBanModalComponent extends FormReactive implements OnInit {
|
||||||
protected formValidatorService: FormValidatorService,
|
protected formValidatorService: FormValidatorService,
|
||||||
private modalService: NgbModal,
|
private modalService: NgbModal,
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private userService: UserService
|
private userAdminService: UserAdminService
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
@ -50,7 +51,7 @@ export class UserBanModalComponent extends FormReactive implements OnInit {
|
||||||
banUser () {
|
banUser () {
|
||||||
const reason = this.form.value['reason'] || undefined
|
const reason = this.form.value['reason'] || undefined
|
||||||
|
|
||||||
this.userService.banUsers(this.usersToBan, reason)
|
this.userAdminService.banUsers(this.usersToBan, reason)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
const message = Array.isArray(this.usersToBan)
|
const message = Array.isArray(this.usersToBan)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, ViewChild } from '@angular/core'
|
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, ViewChild } from '@angular/core'
|
||||||
import { AuthService, ConfirmService, Notifier, ServerService, UserService } from '@app/core'
|
import { AuthService, ConfirmService, Notifier, ServerService } from '@app/core'
|
||||||
import { Account, DropdownAction } from '@app/shared/shared-main'
|
import { Account, DropdownAction } from '@app/shared/shared-main'
|
||||||
import { BulkRemoveCommentsOfBody, User, UserRight } from '@shared/models'
|
import { BulkRemoveCommentsOfBody, User, UserRight } from '@shared/models'
|
||||||
|
import { UserAdminService } from '../shared-users'
|
||||||
import { BlocklistService } from './blocklist.service'
|
import { BlocklistService } from './blocklist.service'
|
||||||
import { BulkService } from './bulk.service'
|
import { BulkService } from './bulk.service'
|
||||||
import { UserBanModalComponent } from './user-ban-modal.component'
|
import { UserBanModalComponent } from './user-ban-modal.component'
|
||||||
|
@ -35,7 +36,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges {
|
||||||
private notifier: Notifier,
|
private notifier: Notifier,
|
||||||
private confirmService: ConfirmService,
|
private confirmService: ConfirmService,
|
||||||
private serverService: ServerService,
|
private serverService: ServerService,
|
||||||
private userService: UserService,
|
private userAdminService: UserAdminService,
|
||||||
private blocklistService: BlocklistService,
|
private blocklistService: BlocklistService,
|
||||||
private bulkService: BulkService
|
private bulkService: BulkService
|
||||||
) { }
|
) { }
|
||||||
|
@ -66,7 +67,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges {
|
||||||
const res = await this.confirmService.confirm($localize`Do you really want to unban ${user.username}?`, $localize`Unban`)
|
const res = await this.confirmService.confirm($localize`Do you really want to unban ${user.username}?`, $localize`Unban`)
|
||||||
if (res === false) return
|
if (res === false) return
|
||||||
|
|
||||||
this.userService.unbanUsers(user)
|
this.userAdminService.unbanUsers(user)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success($localize`User ${user.username} unbanned.`)
|
this.notifier.success($localize`User ${user.username} unbanned.`)
|
||||||
|
@ -87,7 +88,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges {
|
||||||
const res = await this.confirmService.confirm(message, $localize`Delete ${user.username}`)
|
const res = await this.confirmService.confirm(message, $localize`Delete ${user.username}`)
|
||||||
if (res === false) return
|
if (res === false) return
|
||||||
|
|
||||||
this.userService.removeUser(user)
|
this.userAdminService.removeUser(user)
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success($localize`User ${user.username} deleted.`)
|
this.notifier.success($localize`User ${user.username} deleted.`)
|
||||||
|
@ -99,7 +100,7 @@ export class UserModerationDropdownComponent implements OnInit, OnChanges {
|
||||||
}
|
}
|
||||||
|
|
||||||
setEmailAsVerified (user: User) {
|
setEmailAsVerified (user: User) {
|
||||||
this.userService.updateUser(user.id, { emailVerified: true })
|
this.userAdminService.updateUser(user.id, { emailVerified: true })
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notifier.success($localize`User ${user.username} email set as verified`)
|
this.notifier.success($localize`User ${user.username} email set as verified`)
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
export * from './user-admin.service'
|
||||||
|
export * from './user-signup.service'
|
||||||
|
|
||||||
|
export * from './shared-users.module'
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
import { NgModule } from '@angular/core'
|
||||||
|
import { SharedMainModule } from '../shared-main/shared-main.module'
|
||||||
|
import { UserAdminService } from './user-admin.service'
|
||||||
|
import { UserSignupService } from './user-signup.service'
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
SharedMainModule
|
||||||
|
],
|
||||||
|
|
||||||
|
declarations: [ ],
|
||||||
|
|
||||||
|
exports: [],
|
||||||
|
|
||||||
|
providers: [
|
||||||
|
UserSignupService,
|
||||||
|
UserAdminService
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class SharedUsersModule { }
|
|
@ -0,0 +1,139 @@
|
||||||
|
import { SortMeta } from 'primeng/api'
|
||||||
|
import { from, Observable } from 'rxjs'
|
||||||
|
import { catchError, concatMap, map, toArray } from 'rxjs/operators'
|
||||||
|
import { HttpClient, HttpParams } from '@angular/common/http'
|
||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { RestExtractor, RestPagination, RestService, UserService } from '@app/core'
|
||||||
|
import { getBytes } from '@root-helpers/bytes'
|
||||||
|
import { ResultList, User as UserServerModel, UserCreate, UserRole, UserUpdate } from '@shared/models'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserAdminService {
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
private authHttp: HttpClient,
|
||||||
|
private restExtractor: RestExtractor,
|
||||||
|
private restService: RestService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
addUser (userCreate: UserCreate) {
|
||||||
|
return this.authHttp.post(UserService.BASE_USERS_URL, userCreate)
|
||||||
|
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUser (userId: number, userUpdate: UserUpdate) {
|
||||||
|
return this.authHttp.put(UserService.BASE_USERS_URL + userId, userUpdate)
|
||||||
|
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUsers (users: UserServerModel[], userUpdate: UserUpdate) {
|
||||||
|
return from(users)
|
||||||
|
.pipe(
|
||||||
|
concatMap(u => this.authHttp.put(UserService.BASE_USERS_URL + u.id, userUpdate)),
|
||||||
|
toArray(),
|
||||||
|
catchError(err => this.restExtractor.handleError(err))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
getUsers (parameters: {
|
||||||
|
pagination: RestPagination
|
||||||
|
sort: SortMeta
|
||||||
|
search?: string
|
||||||
|
}): Observable<ResultList<UserServerModel>> {
|
||||||
|
const { pagination, sort, search } = parameters
|
||||||
|
|
||||||
|
let params = new HttpParams()
|
||||||
|
params = this.restService.addRestGetParams(params, pagination, sort)
|
||||||
|
|
||||||
|
if (search) {
|
||||||
|
const filters = this.restService.parseQueryStringFilter(search, {
|
||||||
|
blocked: {
|
||||||
|
prefix: 'banned:',
|
||||||
|
isBoolean: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
params = this.restService.addObjectParams(params, filters)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.authHttp.get<ResultList<UserServerModel>>(UserService.BASE_USERS_URL, { params })
|
||||||
|
.pipe(
|
||||||
|
map(res => this.restExtractor.convertResultListDateToHuman(res)),
|
||||||
|
map(res => this.restExtractor.applyToResultListData(res, this.formatUser.bind(this))),
|
||||||
|
catchError(err => this.restExtractor.handleError(err))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
removeUser (usersArg: UserServerModel | UserServerModel[]) {
|
||||||
|
const users = Array.isArray(usersArg) ? usersArg : [ usersArg ]
|
||||||
|
|
||||||
|
return from(users)
|
||||||
|
.pipe(
|
||||||
|
concatMap(u => this.authHttp.delete(UserService.BASE_USERS_URL + u.id)),
|
||||||
|
toArray(),
|
||||||
|
catchError(err => this.restExtractor.handleError(err))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
banUsers (usersArg: UserServerModel | UserServerModel[], reason?: string) {
|
||||||
|
const body = reason ? { reason } : {}
|
||||||
|
const users = Array.isArray(usersArg) ? usersArg : [ usersArg ]
|
||||||
|
|
||||||
|
return from(users)
|
||||||
|
.pipe(
|
||||||
|
concatMap(u => this.authHttp.post(UserService.BASE_USERS_URL + u.id + '/block', body)),
|
||||||
|
toArray(),
|
||||||
|
catchError(err => this.restExtractor.handleError(err))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
unbanUsers (usersArg: UserServerModel | UserServerModel[]) {
|
||||||
|
const users = Array.isArray(usersArg) ? usersArg : [ usersArg ]
|
||||||
|
|
||||||
|
return from(users)
|
||||||
|
.pipe(
|
||||||
|
concatMap(u => this.authHttp.post(UserService.BASE_USERS_URL + u.id + '/unblock', {})),
|
||||||
|
toArray(),
|
||||||
|
catchError(err => this.restExtractor.handleError(err))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private formatUser (user: UserServerModel) {
|
||||||
|
let videoQuota
|
||||||
|
if (user.videoQuota === -1) {
|
||||||
|
videoQuota = '∞'
|
||||||
|
} else {
|
||||||
|
videoQuota = getBytes(user.videoQuota, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const videoQuotaUsed = getBytes(user.videoQuotaUsed, 0)
|
||||||
|
|
||||||
|
let videoQuotaDaily: string
|
||||||
|
let videoQuotaUsedDaily: string
|
||||||
|
if (user.videoQuotaDaily === -1) {
|
||||||
|
videoQuotaDaily = '∞'
|
||||||
|
videoQuotaUsedDaily = getBytes(0, 0) + ''
|
||||||
|
} else {
|
||||||
|
videoQuotaDaily = getBytes(user.videoQuotaDaily, 0) + ''
|
||||||
|
videoQuotaUsedDaily = getBytes(user.videoQuotaUsedDaily || 0, 0) + ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const roleLabels: { [ id in UserRole ]: string } = {
|
||||||
|
[UserRole.USER]: $localize`User`,
|
||||||
|
[UserRole.ADMINISTRATOR]: $localize`Administrator`,
|
||||||
|
[UserRole.MODERATOR]: $localize`Moderator`
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.assign(user, {
|
||||||
|
roleLabel: roleLabels[user.role],
|
||||||
|
videoQuota,
|
||||||
|
videoQuotaUsed,
|
||||||
|
rawVideoQuota: user.videoQuota,
|
||||||
|
rawVideoQuotaUsed: user.videoQuotaUsed,
|
||||||
|
videoQuotaDaily,
|
||||||
|
videoQuotaUsedDaily,
|
||||||
|
rawVideoQuotaDaily: user.videoQuotaDaily,
|
||||||
|
rawVideoQuotaUsedDaily: user.videoQuotaUsedDaily
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { catchError, tap } from 'rxjs/operators'
|
||||||
|
import { HttpClient } from '@angular/common/http'
|
||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { RestExtractor, UserService } from '@app/core'
|
||||||
|
import { UserRegister } from '@shared/models'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserSignupService {
|
||||||
|
constructor (
|
||||||
|
private authHttp: HttpClient,
|
||||||
|
private restExtractor: RestExtractor,
|
||||||
|
private userService: UserService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
signup (userCreate: UserRegister) {
|
||||||
|
return this.authHttp.post(UserService.BASE_USERS_URL + 'register', userCreate)
|
||||||
|
.pipe(
|
||||||
|
tap(() => this.userService.setSignupInThisSession(true)),
|
||||||
|
catchError(err => this.restExtractor.handleError(err))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyEmail (userId: number, verificationString: string, isPendingEmail: boolean) {
|
||||||
|
const url = `${UserService.BASE_USERS_URL}/${userId}/verify-email`
|
||||||
|
const body = {
|
||||||
|
verificationString,
|
||||||
|
isPendingEmail
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.authHttp.post(url, body)
|
||||||
|
.pipe(catchError(res => this.restExtractor.handleError(res)))
|
||||||
|
}
|
||||||
|
|
||||||
|
askSendVerifyEmail (email: string) {
|
||||||
|
const url = UserService.BASE_USERS_URL + '/ask-send-verify-email'
|
||||||
|
|
||||||
|
return this.authHttp.post(url, { email })
|
||||||
|
.pipe(catchError(err => this.restExtractor.handleError(err)))
|
||||||
|
}
|
||||||
|
|
||||||
|
getNewUsername (oldDisplayName: string, newDisplayName: string, currentUsername: string) {
|
||||||
|
// Don't update display name, the user seems to have changed it
|
||||||
|
if (this.displayNameToUsername(oldDisplayName) !== currentUsername) return currentUsername
|
||||||
|
|
||||||
|
return this.displayNameToUsername(newDisplayName)
|
||||||
|
}
|
||||||
|
|
||||||
|
private displayNameToUsername (displayName: string) {
|
||||||
|
if (!displayName) return ''
|
||||||
|
|
||||||
|
return displayName
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/\s/g, '_')
|
||||||
|
.replace(/[^a-z0-9_.]/g, '')
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue