diff options
author | Chocobozzz <me@florianbigard.com> | 2022-10-07 11:06:28 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-10-07 11:06:28 +0200 |
commit | d12b40fb96d56786a96c06a621f3d8e0a0d24f4a (patch) | |
tree | 7047fa5cd7e778eb377c897eccb539c52b2e59bc /client/src/app/+login/login.component.ts | |
parent | 56f47830758ff8e92abcfcc5f35d474ab12fe215 (diff) | |
download | PeerTube-d12b40fb96d56786a96c06a621f3d8e0a0d24f4a.tar.gz PeerTube-d12b40fb96d56786a96c06a621f3d8e0a0d24f4a.tar.zst PeerTube-d12b40fb96d56786a96c06a621f3d8e0a0d24f4a.zip |
Implement two factor in client
Diffstat (limited to 'client/src/app/+login/login.component.ts')
-rw-r--r-- | client/src/app/+login/login.component.ts | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/client/src/app/+login/login.component.ts b/client/src/app/+login/login.component.ts index 2ed9be16c..9095e43a7 100644 --- a/client/src/app/+login/login.component.ts +++ b/client/src/app/+login/login.component.ts | |||
@@ -4,7 +4,8 @@ import { ActivatedRoute, Router } from '@angular/router' | |||
4 | import { AuthService, Notifier, RedirectService, SessionStorageService, UserService } from '@app/core' | 4 | import { AuthService, Notifier, RedirectService, SessionStorageService, UserService } from '@app/core' |
5 | import { HooksService } from '@app/core/plugins/hooks.service' | 5 | import { HooksService } from '@app/core/plugins/hooks.service' |
6 | import { LOGIN_PASSWORD_VALIDATOR, LOGIN_USERNAME_VALIDATOR } from '@app/shared/form-validators/login-validators' | 6 | import { LOGIN_PASSWORD_VALIDATOR, LOGIN_USERNAME_VALIDATOR } from '@app/shared/form-validators/login-validators' |
7 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' | 7 | import { USER_OTP_TOKEN_VALIDATOR } from '@app/shared/form-validators/user-validators' |
8 | import { FormReactive, FormValidatorService, InputTextComponent } from '@app/shared/shared-forms' | ||
8 | import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance' | 9 | import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance' |
9 | import { NgbAccordion, NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap' | 10 | import { NgbAccordion, NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap' |
10 | import { PluginsManager } from '@root-helpers/plugins-manager' | 11 | import { PluginsManager } from '@root-helpers/plugins-manager' |
@@ -20,6 +21,7 @@ export class LoginComponent extends FormReactive implements OnInit, AfterViewIni | |||
20 | private static SESSION_STORAGE_REDIRECT_URL_KEY = 'login-previous-url' | 21 | private static SESSION_STORAGE_REDIRECT_URL_KEY = 'login-previous-url' |
21 | 22 | ||
22 | @ViewChild('forgotPasswordModal', { static: true }) forgotPasswordModal: ElementRef | 23 | @ViewChild('forgotPasswordModal', { static: true }) forgotPasswordModal: ElementRef |
24 | @ViewChild('otpTokenInput') otpTokenInput: InputTextComponent | ||
23 | 25 | ||
24 | accordion: NgbAccordion | 26 | accordion: NgbAccordion |
25 | error: string = null | 27 | error: string = null |
@@ -37,6 +39,8 @@ export class LoginComponent extends FormReactive implements OnInit, AfterViewIni | |||
37 | codeOfConduct: false | 39 | codeOfConduct: false |
38 | } | 40 | } |
39 | 41 | ||
42 | otpStep = false | ||
43 | |||
40 | private openedForgotPasswordModal: NgbModalRef | 44 | private openedForgotPasswordModal: NgbModalRef |
41 | private serverConfig: ServerConfig | 45 | private serverConfig: ServerConfig |
42 | 46 | ||
@@ -82,7 +86,11 @@ export class LoginComponent extends FormReactive implements OnInit, AfterViewIni | |||
82 | // Avoid undefined errors when accessing form error properties | 86 | // Avoid undefined errors when accessing form error properties |
83 | this.buildForm({ | 87 | this.buildForm({ |
84 | username: LOGIN_USERNAME_VALIDATOR, | 88 | username: LOGIN_USERNAME_VALIDATOR, |
85 | password: LOGIN_PASSWORD_VALIDATOR | 89 | password: LOGIN_PASSWORD_VALIDATOR, |
90 | 'otp-token': { | ||
91 | VALIDATORS: [], // Will be set dynamically | ||
92 | MESSAGES: USER_OTP_TOKEN_VALIDATOR.MESSAGES | ||
93 | } | ||
86 | }) | 94 | }) |
87 | 95 | ||
88 | this.serverConfig = snapshot.data.serverConfig | 96 | this.serverConfig = snapshot.data.serverConfig |
@@ -118,13 +126,20 @@ export class LoginComponent extends FormReactive implements OnInit, AfterViewIni | |||
118 | login () { | 126 | login () { |
119 | this.error = null | 127 | this.error = null |
120 | 128 | ||
121 | const { username, password } = this.form.value | 129 | const options = { |
130 | username: this.form.value['username'], | ||
131 | password: this.form.value['password'], | ||
132 | otpToken: this.form.value['otp-token'] | ||
133 | } | ||
122 | 134 | ||
123 | this.authService.login(username, password) | 135 | this.authService.login(options) |
136 | .pipe() | ||
124 | .subscribe({ | 137 | .subscribe({ |
125 | next: () => this.redirectService.redirectToPreviousRoute(), | 138 | next: () => this.redirectService.redirectToPreviousRoute(), |
126 | 139 | ||
127 | error: err => this.handleError(err) | 140 | error: err => { |
141 | this.handleError(err) | ||
142 | } | ||
128 | }) | 143 | }) |
129 | } | 144 | } |
130 | 145 | ||
@@ -162,7 +177,7 @@ The link will expire within 1 hour.` | |||
162 | private loadExternalAuthToken (username: string, token: string) { | 177 | private loadExternalAuthToken (username: string, token: string) { |
163 | this.isAuthenticatedWithExternalAuth = true | 178 | this.isAuthenticatedWithExternalAuth = true |
164 | 179 | ||
165 | this.authService.login(username, null, token) | 180 | this.authService.login({ username, password: null, token }) |
166 | .subscribe({ | 181 | .subscribe({ |
167 | next: () => { | 182 | next: () => { |
168 | const redirectUrl = this.storage.getItem(LoginComponent.SESSION_STORAGE_REDIRECT_URL_KEY) | 183 | const redirectUrl = this.storage.getItem(LoginComponent.SESSION_STORAGE_REDIRECT_URL_KEY) |
@@ -182,6 +197,17 @@ The link will expire within 1 hour.` | |||
182 | } | 197 | } |
183 | 198 | ||
184 | private handleError (err: any) { | 199 | private handleError (err: any) { |
200 | if (this.authService.isOTPMissingError(err)) { | ||
201 | this.otpStep = true | ||
202 | |||
203 | setTimeout(() => { | ||
204 | this.form.get('otp-token').setValidators(USER_OTP_TOKEN_VALIDATOR.VALIDATORS) | ||
205 | this.otpTokenInput.focus() | ||
206 | }) | ||
207 | |||
208 | return | ||
209 | } | ||
210 | |||
185 | if (err.message.indexOf('credentials are invalid') !== -1) this.error = $localize`Incorrect username or password.` | 211 | if (err.message.indexOf('credentials are invalid') !== -1) this.error = $localize`Incorrect username or password.` |
186 | else if (err.message.indexOf('blocked') !== -1) this.error = $localize`Your account is blocked.` | 212 | else if (err.message.indexOf('blocked') !== -1) this.error = $localize`Your account is blocked.` |
187 | else this.error = err.message | 213 | else this.error = err.message |