Split de la page de login en 2 composants
This commit is contained in:
@@ -44,11 +44,14 @@ import { MatPaginatorModule } from "@angular/material/paginator";
|
|||||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||||
import { MatSelectModule } from "@angular/material/select";
|
import { MatSelectModule } from "@angular/material/select";
|
||||||
import { MatTableModule } from "@angular/material/table";
|
import { MatTableModule } from "@angular/material/table";
|
||||||
|
import { MatTabsModule } from "@angular/material/tabs";
|
||||||
|
|
||||||
import { CachingInterceptor } from "../interceptor/caching.interceptor";
|
import { CachingInterceptor } from "../interceptor/caching.interceptor";
|
||||||
//import { BasicAuthInterceptor } from '../interceptor/basic-auth.interceptor';
|
//import { BasicAuthInterceptor } from '../interceptor/basic-auth.interceptor';
|
||||||
import { JwtAuthInterceptor } from "../interceptor/jwt-auth.interceptor";
|
import { JwtAuthInterceptor } from "../interceptor/jwt-auth.interceptor";
|
||||||
import { ErrorInterceptor } from "../interceptor/error.interceptor";
|
import { ErrorInterceptor } from "../interceptor/error.interceptor";
|
||||||
|
import { CreateUserComponent } from "./create-user/create-user.component";
|
||||||
|
import { LoginUserComponent } from "./login-user/login-user.component";
|
||||||
|
|
||||||
const appRoutes: Routes = [
|
const appRoutes: Routes = [
|
||||||
{ path: "", component: DefaultComponent, canActivate: [AuthGuardService] },
|
{ path: "", component: DefaultComponent, canActivate: [AuthGuardService] },
|
||||||
@@ -109,7 +112,9 @@ const appRoutes: Routes = [
|
|||||||
NewDropZoneComponent,
|
NewDropZoneComponent,
|
||||||
NewJumpTypeComponent,
|
NewJumpTypeComponent,
|
||||||
DefaultComponent,
|
DefaultComponent,
|
||||||
LoginComponent
|
LoginComponent,
|
||||||
|
CreateUserComponent,
|
||||||
|
LoginUserComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
RouterModule.forRoot(
|
RouterModule.forRoot(
|
||||||
@@ -132,7 +137,8 @@ const appRoutes: Routes = [
|
|||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatAutocompleteModule,
|
MatAutocompleteModule,
|
||||||
MatProgressSpinnerModule
|
MatProgressSpinnerModule,
|
||||||
|
MatTabsModule
|
||||||
],
|
],
|
||||||
exports: [HttpClientModule],
|
exports: [HttpClientModule],
|
||||||
providers: [
|
providers: [
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<form [formGroup]="createForm" (ngSubmit)="onCreateSubmit()">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input type="text" formControlName="username" class="form-control"
|
||||||
|
[ngClass]="{ 'is-invalid': submitted && createCtrls.username.errors }" />
|
||||||
|
<div *ngIf="submitted && createCtrls.username.errors" class="invalid-feedback">
|
||||||
|
<div *ngIf="createCtrls.username.errors.required">Username is required</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" formControlName="password" class="form-control"
|
||||||
|
[ngClass]="{ 'is-invalid': submitted && createCtrls.password.errors }" />
|
||||||
|
<div *ngIf="submitted && createCtrls.password.errors" class="invalid-feedback">
|
||||||
|
<div *ngIf="createCtrls.password.errors.required">Password is required</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="firstname">Firstname</label>
|
||||||
|
<input type="text" formControlName="firstname" class="form-control"
|
||||||
|
[ngClass]="{ 'is-invalid': submitted && createCtrls.firstname.errors }" />
|
||||||
|
<div *ngIf="submitted && createCtrls.firstname.errors" class="invalid-feedback">
|
||||||
|
<div *ngIf="createCtrls.firstname.errors.required">Firstname is required</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="lastname">Lastname</label>
|
||||||
|
<input type="text" formControlName="lastname" class="form-control"
|
||||||
|
[ngClass]="{ 'is-invalid': submitted && createCtrls.lastname.errors }" />
|
||||||
|
<div *ngIf="submitted && createCtrls.lastname.errors" class="invalid-feedback">
|
||||||
|
<div *ngIf="createCtrls.lastname.errors.required">Lastname is required</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email">E-mail</label>
|
||||||
|
<input type="text" formControlName="email" class="form-control"
|
||||||
|
[ngClass]="{ 'is-invalid': submitted && createCtrls.email.errors }" />
|
||||||
|
<div *ngIf="submitted && createCtrls.email.errors" class="invalid-feedback">
|
||||||
|
<div *ngIf="createCtrls.email.errors.required">E-mail is required</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button [disabled]="loading" class="btn btn-primary">
|
||||||
|
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
|
||||||
|
Create user and login
|
||||||
|
</button>
|
||||||
|
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CreateUserComponent } from './create-user.component';
|
||||||
|
|
||||||
|
describe('CreateUserComponent', () => {
|
||||||
|
let component: CreateUserComponent;
|
||||||
|
let fixture: ComponentFixture<CreateUserComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CreateUserComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CreateUserComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { Router, ActivatedRoute } from "@angular/router";
|
||||||
|
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||||
|
|
||||||
|
import { first } from "rxjs/operators";
|
||||||
|
|
||||||
|
import { AuthenticationService } from "../../services/authentication.service";
|
||||||
|
import { User } from "../../models/user";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-create-user",
|
||||||
|
templateUrl: "./create-user.component.html",
|
||||||
|
styleUrls: ["./create-user.component.css"]
|
||||||
|
})
|
||||||
|
export class CreateUserComponent implements OnInit {
|
||||||
|
createForm: FormGroup;
|
||||||
|
loading = false;
|
||||||
|
submitted = false;
|
||||||
|
returnUrl: string;
|
||||||
|
error = "";
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
|
private authenticationService: AuthenticationService
|
||||||
|
) {
|
||||||
|
// redirect to home if already logged in
|
||||||
|
if (this.authenticationService.currentUserValue) {
|
||||||
|
this.router.navigate(["/"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.createForm = this.formBuilder.group({
|
||||||
|
username: ["", Validators.required],
|
||||||
|
password: ["", Validators.required],
|
||||||
|
firstname: ["", Validators.required],
|
||||||
|
lastname: ["", Validators.required],
|
||||||
|
email: ["", Validators.required]
|
||||||
|
});
|
||||||
|
|
||||||
|
// get return url from route parameters or default to '/'
|
||||||
|
this.returnUrl = this.route.snapshot.queryParams["returnUrl"] || "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
get createCtrls() {
|
||||||
|
return this.createForm.controls;
|
||||||
|
}
|
||||||
|
|
||||||
|
onCreateSubmit() {
|
||||||
|
this.submitted = true;
|
||||||
|
|
||||||
|
// stop here if form is invalid
|
||||||
|
if (this.createForm.invalid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
let createUser = new User();
|
||||||
|
createUser.login = this.createCtrls.username.value;
|
||||||
|
createUser.password = this.createCtrls.password.value;
|
||||||
|
createUser.firstName = this.createCtrls.firstname.value;
|
||||||
|
createUser.lastName = this.createCtrls.lastname.value;
|
||||||
|
createUser.email = this.createCtrls.email.value;
|
||||||
|
|
||||||
|
this.authenticationService
|
||||||
|
.create(createUser)
|
||||||
|
.pipe(first())
|
||||||
|
.subscribe(
|
||||||
|
data => {
|
||||||
|
this.router.navigate([this.returnUrl]);
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.error = error;
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<form [formGroup]="loginForm" (ngSubmit)="onLoginSubmit()">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input type="text" formControlName="username" class="form-control"
|
||||||
|
[ngClass]="{ 'is-invalid': submitted && loginCtrls.username.errors }" />
|
||||||
|
<div *ngIf="submitted && loginCtrls.username.errors" class="invalid-feedback">
|
||||||
|
<div *ngIf="loginCtrls.username.errors.required">Username is required</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" formControlName="password" class="form-control"
|
||||||
|
[ngClass]="{ 'is-invalid': submitted && loginCtrls.password.errors }" />
|
||||||
|
<div *ngIf="submitted && loginCtrls.password.errors" class="invalid-feedback">
|
||||||
|
<div *ngIf="loginCtrls.password.errors.required">Password is required</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button [disabled]="loading" class="btn btn-primary">
|
||||||
|
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LoginUserComponent } from './login-user.component';
|
||||||
|
|
||||||
|
describe('LoginUserComponent', () => {
|
||||||
|
let component: LoginUserComponent;
|
||||||
|
let fixture: ComponentFixture<LoginUserComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ LoginUserComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(LoginUserComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { Router, ActivatedRoute } from "@angular/router";
|
||||||
|
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||||
|
|
||||||
|
import { first } from "rxjs/operators";
|
||||||
|
|
||||||
|
import { AuthenticationService } from "../../services/authentication.service";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-login-user",
|
||||||
|
templateUrl: "./login-user.component.html",
|
||||||
|
styleUrls: ["./login-user.component.css"]
|
||||||
|
})
|
||||||
|
export class LoginUserComponent implements OnInit {
|
||||||
|
loginForm: FormGroup;
|
||||||
|
loading = false;
|
||||||
|
submitted = false;
|
||||||
|
returnUrl: string;
|
||||||
|
error = "";
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
|
private authenticationService: AuthenticationService
|
||||||
|
) {
|
||||||
|
// redirect to home if already logged in
|
||||||
|
if (this.authenticationService.currentUserValue) {
|
||||||
|
this.router.navigate(["/"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.loginForm = this.formBuilder.group({
|
||||||
|
username: ["", Validators.required],
|
||||||
|
password: ["", Validators.required]
|
||||||
|
});
|
||||||
|
|
||||||
|
// get return url from route parameters or default to '/'
|
||||||
|
this.returnUrl = this.route.snapshot.queryParams["returnUrl"] || "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
get loginCtrls() {
|
||||||
|
return this.loginForm.controls;
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoginSubmit() {
|
||||||
|
this.submitted = true;
|
||||||
|
|
||||||
|
// stop here if form is invalid
|
||||||
|
if (this.loginForm.invalid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loading = true;
|
||||||
|
this.authenticationService
|
||||||
|
.login(this.loginCtrls.username.value, this.loginCtrls.password.value)
|
||||||
|
.pipe(first())
|
||||||
|
.subscribe(
|
||||||
|
data => {
|
||||||
|
this.router.navigate([this.returnUrl]);
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.error = error;
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,53 +2,16 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h4 class="card-header">Login to the Skydive log</h4>
|
<h4 class="card-header">Login to the Skydive log</h4>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form [formGroup]="loginForm" (ngSubmit)="onLoginSubmit()">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="username">Username</label>
|
|
||||||
<input type="text" formControlName="username" class="form-control"
|
|
||||||
[ngClass]="{ 'is-invalid': submitted && loginCtrls.username.errors }" />
|
|
||||||
<div *ngIf="submitted && loginCtrls.username.errors" class="invalid-feedback">
|
|
||||||
<div *ngIf="loginCtrls.username.errors.required">Username is required</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="password">Password</label>
|
|
||||||
<input type="password" formControlName="password" class="form-control"
|
|
||||||
[ngClass]="{ 'is-invalid': submitted && loginCtrls.password.errors }" />
|
|
||||||
<div *ngIf="submitted && loginCtrls.password.errors" class="invalid-feedback">
|
|
||||||
<div *ngIf="loginCtrls.password.errors.required">Password is required</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button [disabled]="loading" class="btn btn-primary">
|
|
||||||
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
|
|
||||||
Login
|
|
||||||
</button>
|
|
||||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form [formGroup]="createForm" (ngSubmit)="onCreateSubmit()">
|
<mat-tab-group mat-align-tabs="center" animationDuration="0ms">
|
||||||
<div class="form-group">
|
<mat-tab label="Login with a user">
|
||||||
<label for="username">Username</label>
|
<app-login-user></app-login-user>
|
||||||
<input type="text" formControlName="username" class="form-control"
|
</mat-tab>
|
||||||
[ngClass]="{ 'is-invalid': submitted && createCtrls.username.errors }" />
|
<mat-tab label="Create and login a user">
|
||||||
<div *ngIf="submitted && createCtrls.username.errors" class="invalid-feedback">
|
<app-create-user></app-create-user>
|
||||||
<div *ngIf="createCtrls.username.errors.required">Username is required</div>
|
</mat-tab>
|
||||||
</div>
|
</mat-tab-group>
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="password">Password</label>
|
|
||||||
<input type="password" formControlName="password" class="form-control"
|
|
||||||
[ngClass]="{ 'is-invalid': submitted && createCtrls.password.errors }" />
|
|
||||||
<div *ngIf="submitted && createCtrls.password.errors" class="invalid-feedback">
|
|
||||||
<div *ngIf="createCtrls.password.errors.required">Password is required</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button [disabled]="loading" class="btn btn-primary">
|
|
||||||
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
|
|
||||||
Create user and login
|
|
||||||
</button>
|
|
||||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,11 +1,4 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { Router, ActivatedRoute } from "@angular/router";
|
|
||||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
|
||||||
|
|
||||||
import { first } from "rxjs/operators";
|
|
||||||
|
|
||||||
import { AuthenticationService } from "../../services/authentication.service";
|
|
||||||
import { User } from "../../models/user";
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-login",
|
selector: "app-login",
|
||||||
@@ -13,94 +6,7 @@ import { User } from "../../models/user";
|
|||||||
styleUrls: ["./login.component.css"]
|
styleUrls: ["./login.component.css"]
|
||||||
})
|
})
|
||||||
export class LoginComponent implements OnInit {
|
export class LoginComponent implements OnInit {
|
||||||
loginForm: FormGroup;
|
constructor() {}
|
||||||
createForm: FormGroup;
|
|
||||||
loading = false;
|
|
||||||
submitted = false;
|
|
||||||
returnUrl: string;
|
|
||||||
error = "";
|
|
||||||
|
|
||||||
constructor(
|
ngOnInit() {}
|
||||||
private formBuilder: FormBuilder,
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private router: Router,
|
|
||||||
private authenticationService: AuthenticationService
|
|
||||||
) {
|
|
||||||
// redirect to home if already logged in
|
|
||||||
if (this.authenticationService.currentUserValue) {
|
|
||||||
this.router.navigate(["/"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.loginForm = this.formBuilder.group({
|
|
||||||
username: ["", Validators.required],
|
|
||||||
password: ["", Validators.required]
|
|
||||||
});
|
|
||||||
this.createForm = this.formBuilder.group({
|
|
||||||
username: ["", Validators.required],
|
|
||||||
password: ["", Validators.required]
|
|
||||||
});
|
|
||||||
|
|
||||||
// get return url from route parameters or default to '/'
|
|
||||||
this.returnUrl = this.route.snapshot.queryParams["returnUrl"] || "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
get loginCtrls() {
|
|
||||||
return this.loginForm.controls;
|
|
||||||
}
|
|
||||||
|
|
||||||
get createCtrls() {
|
|
||||||
return this.createForm.controls;
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoginSubmit() {
|
|
||||||
this.submitted = true;
|
|
||||||
|
|
||||||
// stop here if form is invalid
|
|
||||||
if (this.loginForm.invalid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loading = true;
|
|
||||||
this.authenticationService
|
|
||||||
.login(this.loginCtrls.username.value, this.loginCtrls.password.value)
|
|
||||||
.pipe(first())
|
|
||||||
.subscribe(
|
|
||||||
data => {
|
|
||||||
this.router.navigate([this.returnUrl]);
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
this.error = error;
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
onCreateSubmit() {
|
|
||||||
this.submitted = true;
|
|
||||||
|
|
||||||
// stop here if form is invalid
|
|
||||||
if (this.createForm.invalid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loading = true;
|
|
||||||
let createUser = new User();
|
|
||||||
createUser.login = this.createCtrls.username.value;
|
|
||||||
createUser.password = this.createCtrls.password.value;
|
|
||||||
|
|
||||||
this.authenticationService
|
|
||||||
.create(createUser)
|
|
||||||
.pipe(first())
|
|
||||||
.subscribe(
|
|
||||||
data => {
|
|
||||||
this.router.navigate([this.returnUrl]);
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
this.error = error;
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export class User {
|
|||||||
password: string;
|
password: string;
|
||||||
firstName: string;
|
firstName: string;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
|
email: string;
|
||||||
authdata?: string;
|
authdata?: string;
|
||||||
token?: string;
|
token?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user