From 2166c058f34dff6f91566930d12448805d829de7 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 7 Oct 2022 14:23:42 +0200 Subject: Allow admins to disable two factor auth --- .../users/user-edit/user-edit.component.html | 9 +++- .../users/user-edit/user-edit.component.scss | 16 +++---- .../+admin/overview/users/user-edit/user-edit.ts | 12 +++++ .../users/user-edit/user-update.component.ts | 21 +++++++-- .../my-account-two-factor/index.ts | 1 - .../my-account-two-factor-button.component.ts | 2 +- .../my-account-two-factor.component.ts | 2 +- .../my-account-two-factor/two-factor.service.ts | 52 ---------------------- client/src/app/+my-account/my-account.module.ts | 12 ++--- client/src/app/shared/shared-users/index.ts | 1 + .../app/shared/shared-users/shared-users.module.ts | 4 +- .../app/shared/shared-users/two-factor.service.ts | 52 ++++++++++++++++++++++ 12 files changed, 104 insertions(+), 80 deletions(-) delete mode 100644 client/src/app/+my-account/my-account-settings/my-account-two-factor/two-factor.service.ts create mode 100644 client/src/app/shared/shared-users/two-factor.service.ts (limited to 'client') diff --git a/client/src/app/+admin/overview/users/user-edit/user-edit.component.html b/client/src/app/+admin/overview/users/user-edit/user-edit.component.html index da5879a36..e51ccf808 100644 --- a/client/src/app/+admin/overview/users/user-edit/user-edit.component.html +++ b/client/src/app/+admin/overview/users/user-edit/user-edit.component.html @@ -204,7 +204,7 @@ -
+
@@ -213,7 +213,7 @@
-
+
@@ -222,6 +222,11 @@
+ +
+ + +
diff --git a/client/src/app/+admin/overview/users/user-edit/user-edit.component.scss b/client/src/app/+admin/overview/users/user-edit/user-edit.component.scss index 68fa1215f..698628149 100644 --- a/client/src/app/+admin/overview/users/user-edit/user-edit.component.scss +++ b/client/src/app/+admin/overview/users/user-edit/user-edit.component.scss @@ -48,17 +48,13 @@ my-user-real-quota-info { } .danger-zone { - .reset-password-email { - margin-bottom: 30px; + button { + @include peertube-button; + @include danger-button; + @include disable-outline; - button { - @include peertube-button; - @include danger-button; - @include disable-outline; - - display: block; - margin-top: 0; - } + display: block; + margin-top: 0; } } diff --git a/client/src/app/+admin/overview/users/user-edit/user-edit.ts b/client/src/app/+admin/overview/users/user-edit/user-edit.ts index 6dae4110d..21e9629ab 100644 --- a/client/src/app/+admin/overview/users/user-edit/user-edit.ts +++ b/client/src/app/+admin/overview/users/user-edit/user-edit.ts @@ -60,10 +60,22 @@ export abstract class UserEdit extends FormReactive implements OnInit { ] } + displayDangerZone () { + if (this.isCreation()) return false + if (this.user?.pluginAuth) return false + if (this.auth.getUser().id === this.user.id) return false + + return true + } + resetPassword () { return } + disableTwoFactorAuth () { + return + } + getUserVideoQuota () { return this.form.value['videoQuota'] } diff --git a/client/src/app/+admin/overview/users/user-edit/user-update.component.ts b/client/src/app/+admin/overview/users/user-edit/user-update.component.ts index bab288a67..1482a1902 100644 --- a/client/src/app/+admin/overview/users/user-edit/user-update.component.ts +++ b/client/src/app/+admin/overview/users/user-edit/user-update.component.ts @@ -10,7 +10,7 @@ import { USER_VIDEO_QUOTA_VALIDATOR } from '@app/shared/form-validators/user-validators' import { FormValidatorService } from '@app/shared/shared-forms' -import { UserAdminService } from '@app/shared/shared-users' +import { TwoFactorService, UserAdminService } from '@app/shared/shared-users' import { User as UserType, UserAdminFlag, UserRole, UserUpdate } from '@shared/models' import { UserEdit } from './user-edit' @@ -34,6 +34,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { private router: Router, private notifier: Notifier, private userService: UserService, + private twoFactorService: TwoFactorService, private userAdminService: UserAdminService ) { super() @@ -120,10 +121,22 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy { this.notifier.success($localize`An email asking for password reset has been sent to ${this.user.username}.`) }, - error: err => { - this.error = err.message - } + error: err => this.notifier.error(err.message) + }) + } + + disableTwoFactorAuth () { + this.twoFactorService.disableTwoFactor({ userId: this.user.id }) + .subscribe({ + next: () => { + this.user.twoFactorEnabled = false + + this.notifier.success($localize`Two factor authentication of ${this.user.username} disabled.`) + }, + + error: err => this.notifier.error(err.message) }) + } private onUserFetched (userJson: UserType) { diff --git a/client/src/app/+my-account/my-account-settings/my-account-two-factor/index.ts b/client/src/app/+my-account/my-account-settings/my-account-two-factor/index.ts index ef83009a5..cc774bde3 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-two-factor/index.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-two-factor/index.ts @@ -1,3 +1,2 @@ export * from './my-account-two-factor-button.component' export * from './my-account-two-factor.component' -export * from './two-factor.service' diff --git a/client/src/app/+my-account/my-account-settings/my-account-two-factor/my-account-two-factor-button.component.ts b/client/src/app/+my-account/my-account-settings/my-account-two-factor/my-account-two-factor-button.component.ts index 03b00e933..97ffb6013 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-two-factor/my-account-two-factor-button.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-two-factor/my-account-two-factor-button.component.ts @@ -1,7 +1,7 @@ import { Subject } from 'rxjs' import { Component, Input, OnInit } from '@angular/core' import { AuthService, ConfirmService, Notifier, User } from '@app/core' -import { TwoFactorService } from './two-factor.service' +import { TwoFactorService } from '@app/shared/shared-users' @Component({ selector: 'my-account-two-factor-button', diff --git a/client/src/app/+my-account/my-account-settings/my-account-two-factor/my-account-two-factor.component.ts b/client/src/app/+my-account/my-account-settings/my-account-two-factor/my-account-two-factor.component.ts index e4d4188f7..259090d64 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-two-factor/my-account-two-factor.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-two-factor/my-account-two-factor.component.ts @@ -4,7 +4,7 @@ import { Router } from '@angular/router' import { AuthService, Notifier, User } from '@app/core' import { USER_EXISTING_PASSWORD_VALIDATOR, USER_OTP_TOKEN_VALIDATOR } from '@app/shared/form-validators/user-validators' import { FormReactiveService } from '@app/shared/shared-forms' -import { TwoFactorService } from './two-factor.service' +import { TwoFactorService } from '@app/shared/shared-users' @Component({ selector: 'my-account-two-factor', diff --git a/client/src/app/+my-account/my-account-settings/my-account-two-factor/two-factor.service.ts b/client/src/app/+my-account/my-account-settings/my-account-two-factor/two-factor.service.ts deleted file mode 100644 index c0e5ac492..000000000 --- a/client/src/app/+my-account/my-account-settings/my-account-two-factor/two-factor.service.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { catchError } from 'rxjs/operators' -import { HttpClient } from '@angular/common/http' -import { Injectable } from '@angular/core' -import { RestExtractor, UserService } from '@app/core' -import { TwoFactorEnableResult } from '@shared/models' - -@Injectable() -export class TwoFactorService { - constructor ( - private authHttp: HttpClient, - private restExtractor: RestExtractor - ) { } - - // --------------------------------------------------------------------------- - - requestTwoFactor (options: { - userId: number - currentPassword: string - }) { - const { userId, currentPassword } = options - - const url = UserService.BASE_USERS_URL + userId + '/two-factor/request' - - return this.authHttp.post(url, { currentPassword }) - .pipe(catchError(err => this.restExtractor.handleError(err))) - } - - confirmTwoFactorRequest (options: { - userId: number - requestToken: string - otpToken: string - }) { - const { userId, requestToken, otpToken } = options - - const url = UserService.BASE_USERS_URL + userId + '/two-factor/confirm-request' - - return this.authHttp.post(url, { requestToken, otpToken }) - .pipe(catchError(err => this.restExtractor.handleError(err))) - } - - disableTwoFactor (options: { - userId: number - currentPassword: string - }) { - const { userId, currentPassword } = options - - const url = UserService.BASE_USERS_URL + userId + '/two-factor/disable' - - return this.authHttp.post(url, { currentPassword }) - .pipe(catchError(err => this.restExtractor.handleError(err))) - } -} diff --git a/client/src/app/+my-account/my-account.module.ts b/client/src/app/+my-account/my-account.module.ts index f5beaa4db..84b057647 100644 --- a/client/src/app/+my-account/my-account.module.ts +++ b/client/src/app/+my-account/my-account.module.ts @@ -11,6 +11,7 @@ import { SharedMainModule } from '@app/shared/shared-main' import { SharedModerationModule } from '@app/shared/shared-moderation' import { SharedShareModal } from '@app/shared/shared-share-modal' import { SharedUserInterfaceSettingsModule } from '@app/shared/shared-user-settings' +import { SharedUsersModule } from '@app/shared/shared-users' import { SharedActorImageModule } from '../shared/shared-actor-image/shared-actor-image.module' import { MyAccountAbusesListComponent } from './my-account-abuses/my-account-abuses-list.component' import { MyAccountApplicationsComponent } from './my-account-applications/my-account-applications.component' @@ -24,11 +25,7 @@ import { MyAccountDangerZoneComponent } from './my-account-settings/my-account-d import { MyAccountNotificationPreferencesComponent } from './my-account-settings/my-account-notification-preferences' import { MyAccountProfileComponent } from './my-account-settings/my-account-profile/my-account-profile.component' import { MyAccountSettingsComponent } from './my-account-settings/my-account-settings.component' -import { - MyAccountTwoFactorButtonComponent, - MyAccountTwoFactorComponent, - TwoFactorService -} from './my-account-settings/my-account-two-factor' +import { MyAccountTwoFactorButtonComponent, MyAccountTwoFactorComponent } from './my-account-settings/my-account-two-factor' import { MyAccountComponent } from './my-account.component' @NgModule({ @@ -44,6 +41,7 @@ import { MyAccountComponent } from './my-account.component' SharedFormModule, SharedModerationModule, SharedUserInterfaceSettingsModule, + SharedUsersModule, SharedGlobalIconModule, SharedAbuseListModule, SharedShareModal, @@ -74,9 +72,7 @@ import { MyAccountComponent } from './my-account.component' MyAccountComponent ], - providers: [ - TwoFactorService - ] + providers: [] }) export class MyAccountModule { } diff --git a/client/src/app/shared/shared-users/index.ts b/client/src/app/shared/shared-users/index.ts index 8f90f2515..20e60486d 100644 --- a/client/src/app/shared/shared-users/index.ts +++ b/client/src/app/shared/shared-users/index.ts @@ -1,4 +1,5 @@ export * from './user-admin.service' export * from './user-signup.service' +export * from './two-factor.service' export * from './shared-users.module' diff --git a/client/src/app/shared/shared-users/shared-users.module.ts b/client/src/app/shared/shared-users/shared-users.module.ts index 2a1dadf20..5a1675dc9 100644 --- a/client/src/app/shared/shared-users/shared-users.module.ts +++ b/client/src/app/shared/shared-users/shared-users.module.ts @@ -1,6 +1,7 @@ import { NgModule } from '@angular/core' import { SharedMainModule } from '../shared-main/shared-main.module' +import { TwoFactorService } from './two-factor.service' import { UserAdminService } from './user-admin.service' import { UserSignupService } from './user-signup.service' @@ -15,7 +16,8 @@ import { UserSignupService } from './user-signup.service' providers: [ UserSignupService, - UserAdminService + UserAdminService, + TwoFactorService ] }) export class SharedUsersModule { } diff --git a/client/src/app/shared/shared-users/two-factor.service.ts b/client/src/app/shared/shared-users/two-factor.service.ts new file mode 100644 index 000000000..9ff916f15 --- /dev/null +++ b/client/src/app/shared/shared-users/two-factor.service.ts @@ -0,0 +1,52 @@ +import { catchError } from 'rxjs/operators' +import { HttpClient } from '@angular/common/http' +import { Injectable } from '@angular/core' +import { RestExtractor, UserService } from '@app/core' +import { TwoFactorEnableResult } from '@shared/models' + +@Injectable() +export class TwoFactorService { + constructor ( + private authHttp: HttpClient, + private restExtractor: RestExtractor + ) { } + + // --------------------------------------------------------------------------- + + requestTwoFactor (options: { + userId: number + currentPassword: string + }) { + const { userId, currentPassword } = options + + const url = UserService.BASE_USERS_URL + userId + '/two-factor/request' + + return this.authHttp.post(url, { currentPassword }) + .pipe(catchError(err => this.restExtractor.handleError(err))) + } + + confirmTwoFactorRequest (options: { + userId: number + requestToken: string + otpToken: string + }) { + const { userId, requestToken, otpToken } = options + + const url = UserService.BASE_USERS_URL + userId + '/two-factor/confirm-request' + + return this.authHttp.post(url, { requestToken, otpToken }) + .pipe(catchError(err => this.restExtractor.handleError(err))) + } + + disableTwoFactor (options: { + userId: number + currentPassword?: string + }) { + const { userId, currentPassword } = options + + const url = UserService.BASE_USERS_URL + userId + '/two-factor/disable' + + return this.authHttp.post(url, { currentPassword }) + .pipe(catchError(err => this.restExtractor.handleError(err))) + } +} -- cgit v1.2.3