refactor: rewrite oauth login and 2fa for the new api
This commit is contained in:
parent
a7542eaf32
commit
1d691ccc09
@ -7,6 +7,7 @@ import {AvailableOAuthProvidersResponse} from "@api/v1/availableProvidersRespons
|
|||||||
import {OAuthProvider} from "@model/oAuthProvider";
|
import {OAuthProvider} from "@model/oAuthProvider";
|
||||||
import {TwoFactorAuthentication} from "@model/twoFactorAuthentication";
|
import {TwoFactorAuthentication} from "@model/twoFactorAuthentication";
|
||||||
import {TwoFactorAuthRequest} from "@api/v1/twoFactorAuthRequest";
|
import {TwoFactorAuthRequest} from "@api/v1/twoFactorAuthRequest";
|
||||||
|
import {OAuthAction} from "@model/oAuthAction";
|
||||||
|
|
||||||
export interface OAuthProviderData extends AvailableOAuthProvidersResponse {
|
export interface OAuthProviderData extends AvailableOAuthProvidersResponse {
|
||||||
icon: string;
|
icon: string;
|
||||||
@ -83,9 +84,10 @@ export default class AuthApiService extends ApiService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public availableProviders(): Observable<OAuthProviderData[]> {
|
public availableProviders(callback: string): Observable<OAuthProviderData[]> {
|
||||||
let request = this.createRequestBuilder()
|
let request = this.createRequestBuilder()
|
||||||
.setEndpoint('AvailableProviders')
|
.setEndpoint('AvailableProviders')
|
||||||
|
.setQueryParams({callback: callback})
|
||||||
.setWithCredentials()
|
.setWithCredentials()
|
||||||
.build;
|
.build;
|
||||||
|
|
||||||
@ -97,4 +99,21 @@ export default class AuthApiService extends ApiService {
|
|||||||
}) as OAuthProviderData);
|
}) as OAuthProviderData);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleTokenRequest(token: string, action: OAuthAction) {
|
||||||
|
return this.createRequestBuilder()
|
||||||
|
.setEndpoint('HandleToken')
|
||||||
|
.setQueryParams({token: token, action: action})
|
||||||
|
.setWithCredentials()
|
||||||
|
.build;
|
||||||
|
}
|
||||||
|
|
||||||
|
public loginOAuth(token: string) {
|
||||||
|
return this.get<TwoFactorAuthentication>(this.handleTokenRequest(token, OAuthAction.Login));
|
||||||
|
}
|
||||||
|
|
||||||
|
public linkAccount(token: string): Observable<null> {
|
||||||
|
const request = this.handleTokenRequest(token, OAuthAction.Bind);
|
||||||
|
return this.addAuth(request).get(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<mat-sidenav-container class="formLogin">
|
<mat-sidenav-container class="formLogin">
|
||||||
|
|
||||||
<mat-card>
|
<mat-card>
|
||||||
<p class="mat-h3">
|
<p class="mat-h3">
|
||||||
Вход в систему
|
Вход в систему
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form [formGroup]="loginForm">
|
<form [formGroup]="loginForm">
|
||||||
|
@if (!requiresTwoFactorAuth) {
|
||||||
<mat-form-field color="accent">
|
<mat-form-field color="accent">
|
||||||
<mat-label>Имя пользователя/email</mat-label>
|
<mat-label>Имя пользователя/email</mat-label>
|
||||||
<input matInput
|
<input matInput
|
||||||
@ -28,9 +28,26 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<password-input [focusNext]="'loginNextFocus'" [formGroup]="loginForm"/>
|
<password-input [focusNext]="'loginNextFocus'" [formGroup]="loginForm"/>
|
||||||
|
} @else {
|
||||||
|
<mat-form-field color="accent">
|
||||||
|
<mat-label>Код 2FA</mat-label>
|
||||||
|
<input matInput
|
||||||
|
formControlName="twoFactorCode"
|
||||||
|
matTooltip="Введите код из приложения"
|
||||||
|
required
|
||||||
|
focusNext="loginNextFocus">
|
||||||
|
@if (loginForm.get('twoFactorCode')?.hasError('required')) {
|
||||||
|
<mat-error>
|
||||||
|
Код 2FA обязателен.
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<OAuthProviders/>
|
@if (!requiresTwoFactorAuth) {
|
||||||
|
<OAuthProviders (oAuthLoginResult)="loginOAuth($event)"/>
|
||||||
|
}
|
||||||
|
|
||||||
<mat-error>
|
<mat-error>
|
||||||
{{ errorText }}
|
{{ errorText }}
|
||||||
@ -42,7 +59,7 @@
|
|||||||
} @else {
|
} @else {
|
||||||
<button mat-flat-button color="accent"
|
<button mat-flat-button color="accent"
|
||||||
[disabled]="loginButtonIsDisable"
|
[disabled]="loginButtonIsDisable"
|
||||||
(click)="login()"
|
(click)="requiresTwoFactorAuth ? login2Fa() : login()"
|
||||||
id="loginNextFocus">
|
id="loginNextFocus">
|
||||||
Войти
|
Войти
|
||||||
</button>
|
</button>
|
||||||
|
@ -5,7 +5,7 @@ import {MatInput} from "@angular/material/input";
|
|||||||
import {MatTooltip} from "@angular/material/tooltip";
|
import {MatTooltip} from "@angular/material/tooltip";
|
||||||
import {MatButton} from "@angular/material/button";
|
import {MatButton} from "@angular/material/button";
|
||||||
import {MatCard} from "@angular/material/card";
|
import {MatCard} from "@angular/material/card";
|
||||||
import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
|
import {FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators} from "@angular/forms";
|
||||||
import {FocusNextDirective} from "@/directives/focus-next.directive";
|
import {FocusNextDirective} from "@/directives/focus-next.directive";
|
||||||
import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component";
|
import {DataSpinnerComponent} from "@component/common/data-spinner/data-spinner.component";
|
||||||
import AuthApiService from "@api/v1/authApiService";
|
import AuthApiService from "@api/v1/authApiService";
|
||||||
@ -40,6 +40,7 @@ export class LoginComponent {
|
|||||||
protected loaderActive: boolean = false;
|
protected loaderActive: boolean = false;
|
||||||
protected loginButtonIsDisable: boolean = true;
|
protected loginButtonIsDisable: boolean = true;
|
||||||
protected errorText: string = '';
|
protected errorText: string = '';
|
||||||
|
protected requiresTwoFactorAuth: boolean = false;
|
||||||
|
|
||||||
constructor(private formBuilder: FormBuilder, private auth: AuthApiService, private router: Router) {
|
constructor(private formBuilder: FormBuilder, private auth: AuthApiService, private router: Router) {
|
||||||
this.auth.getRole()
|
this.auth.getRole()
|
||||||
@ -69,6 +70,22 @@ export class LoginComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private updateTwoFactorValidation(data: TwoFactorAuthentication) {
|
||||||
|
if (data === TwoFactorAuthentication.None) {
|
||||||
|
this.router.navigate(['admin']).then();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.requiresTwoFactorAuth = true;
|
||||||
|
this.loginForm.addControl(
|
||||||
|
'twoFactorCode',
|
||||||
|
new FormControl('', Validators.required)
|
||||||
|
);
|
||||||
|
this.loginForm.removeControl('user');
|
||||||
|
this.loginForm.removeControl('password');
|
||||||
|
this.loginButtonIsDisable = !this.loginForm.valid;
|
||||||
|
}
|
||||||
|
|
||||||
protected login() {
|
protected login() {
|
||||||
this.loaderActive = true;
|
this.loaderActive = true;
|
||||||
|
|
||||||
@ -85,11 +102,31 @@ export class LoginComponent {
|
|||||||
.subscribe(x => {
|
.subscribe(x => {
|
||||||
this.loaderActive = false;
|
this.loaderActive = false;
|
||||||
this.errorText = '';
|
this.errorText = '';
|
||||||
|
this.updateTwoFactorValidation(x);
|
||||||
if (x == TwoFactorAuthentication.None)
|
|
||||||
this.router.navigate(['admin']).then();
|
|
||||||
else
|
|
||||||
this.router.navigate(['two-factor']).then();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected login2Fa() {
|
||||||
|
this.loaderActive = true;
|
||||||
|
|
||||||
|
this.auth.twoFactorAuth({
|
||||||
|
code: this.loginForm.get('twoFactorCode')?.value,
|
||||||
|
method: TwoFactorAuthentication.TotpRequired
|
||||||
|
})
|
||||||
|
.pipe(catchError(error => {
|
||||||
|
this.loaderActive = false;
|
||||||
|
this.errorText = error.error.detail;
|
||||||
|
this.loginButtonIsDisable = true;
|
||||||
|
throw error;
|
||||||
|
}))
|
||||||
|
.subscribe(_ => {
|
||||||
|
this.loaderActive = false;
|
||||||
|
this.errorText = '';
|
||||||
|
this.router.navigate(['admin']).then();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected loginOAuth(result: TwoFactorAuthentication) {
|
||||||
|
this.updateTwoFactorValidation(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user