From bd94c42eae708b553aeb80dcbe136a28748c9d37 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sun, 20 Nov 2022 15:53:04 +0100 Subject: [PATCH] Added discord login & removed discord register #128 --- kdb-bot/src/bot_api/abc/auth_service_abc.py | 3 + .../controller/auth_discord_controller.py | 20 ++- kdb-bot/src/bot_api/service/auth_service.py | 18 +++ kdb-web/package-lock.json | 134 ++++-------------- kdb-web/package.json | 6 +- .../components/login/login.component.html | 103 +++++++------- .../auth/components/login/login.component.ts | 95 +++++++++---- .../registration/registration.component.html | 6 - .../registration/registration.component.ts | 106 +------------- kdb-web/src/app/services/auth/auth.service.ts | 9 ++ kdb-web/src/assets/config.json | 2 +- kdb-web/src/assets/i18n/de.json | 1 + kdb-web/src/styles.scss | 2 +- 13 files changed, 210 insertions(+), 295 deletions(-) diff --git a/kdb-bot/src/bot_api/abc/auth_service_abc.py b/kdb-bot/src/bot_api/abc/auth_service_abc.py index 72cbbce1ab..a444cbc486 100644 --- a/kdb-bot/src/bot_api/abc/auth_service_abc.py +++ b/kdb-bot/src/bot_api/abc/auth_service_abc.py @@ -70,6 +70,9 @@ class AuthServiceABC(ABC): @abstractmethod async def login_async(self, user_dto: AuthUserDTO) -> TokenDTO: pass + @abstractmethod + async def login_discord_async(self, oauth_dto: AuthUserDTO) -> TokenDTO: pass + @abstractmethod async def refresh_async(self, token_dto: TokenDTO) -> TokenDTO: pass diff --git a/kdb-bot/src/bot_api/controller/auth_discord_controller.py b/kdb-bot/src/bot_api/controller/auth_discord_controller.py index 781813143e..900552b863 100644 --- a/kdb-bot/src/bot_api/controller/auth_discord_controller.py +++ b/kdb-bot/src/bot_api/controller/auth_discord_controller.py @@ -82,8 +82,18 @@ class AuthDiscordController: ), response['id']) return jsonify(result.to_dict()) - @Route.post(f'{BasePath}/register') - async def discord_register(self): - dto: OAuthDTO = JSONProcessor.process(OAuthDTO, request.get_json(force=True, silent=True)) - await self._auth_service.add_auth_user_by_oauth_async(dto) - return '', 200 + @Route.get(f'{BasePath}/login') + async def discord_login(self) -> Response: + response = self._get_user_from_discord_response() + dto = AuthUserDTO( + 0, + response['username'], + response['discriminator'], + response['email'], + str(uuid.uuid4()), + None, + AuthRoleEnum.normal + ) + + result = await self._auth_service.login_discord_async(dto) + return jsonify(result.to_dict()) diff --git a/kdb-bot/src/bot_api/service/auth_service.py b/kdb-bot/src/bot_api/service/auth_service.py index be0859db20..7903c8b46f 100644 --- a/kdb-bot/src/bot_api/service/auth_service.py +++ b/kdb-bot/src/bot_api/service/auth_service.py @@ -460,6 +460,24 @@ class AuthService(AuthServiceABC): self._db.save_changes() return TokenDTO(token, refresh_token) + async def login_discord_async(self, user_dto: AuthUserDTO) -> TokenDTO: + if user_dto is None: + raise ServiceException(ServiceErrorCode.InvalidData, 'User not set') + + db_user = self._auth_users.find_auth_user_by_email(user_dto.email) + if db_user is None: + await self.add_auth_user_async(user_dto) + # raise ServiceException(ServiceErrorCode.InvalidUser, f'User not found') + + db_user = self._auth_users.get_auth_user_by_email(user_dto.email) + token = self.generate_token(db_user) + refresh_token = self._create_and_save_refresh_token(db_user) + if db_user.forgot_password_id is not None: + db_user.forgot_password_id = None + + self._db.save_changes() + return TokenDTO(token, refresh_token) + async def refresh_async(self, token_dto: TokenDTO) -> TokenDTO: if token_dto is None: raise ServiceException(ServiceErrorCode.InvalidData, f'Token not set') diff --git a/kdb-web/package-lock.json b/kdb-web/package-lock.json index b1efc97124..df66cf23b4 100644 --- a/kdb-web/package-lock.json +++ b/kdb-web/package-lock.json @@ -1,12 +1,12 @@ { "name": "kdb-web", - "version": "0.3.dev70", + "version": "0.3.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "kdb-web", - "version": "0.3.dev70", + "version": "0.3.0", "dependencies": { "@angular/animations": "^14.0.0", "@angular/common": "^14.0.0", @@ -25,7 +25,6 @@ "primeng": "^14.1.2", "rxjs": "~7.5.0", "socket.io-client": "^4.5.3", - "tslib": "^2.3.0", "zone.js": "~0.11.4" }, "devDependencies": { @@ -33,14 +32,14 @@ "@angular/cli": "~14.0.0", "@angular/compiler-cli": "^14.0.0", "@types/jasmine": "~4.0.0", - "@types/node": "^18.8.3", + "@types/node": "^18.11.9", "jasmine-core": "~4.1.0", "karma": "~6.3.0", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.0.0", "karma-jasmine-html-reporter": "~1.7.0", - "ts-node": "~8.3.0", + "tslib": "^2.4.1", "typescript": "~4.7.2" } }, @@ -222,6 +221,12 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/@angular-devkit/build-angular/node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, "node_modules/@angular-devkit/build-webpack": { "version": "0.1402.6", "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.6.tgz", @@ -3200,9 +3205,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.11.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.0.tgz", - "integrity": "sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==", + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", "dev": true }, "node_modules/@types/parse-json": { @@ -3705,12 +3710,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -4982,15 +4981,6 @@ "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", "dev": true }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -7881,12 +7871,6 @@ "semver": "bin/semver.js" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/make-fetch-happen": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", @@ -11730,32 +11714,10 @@ "tree-kill": "cli.js" } }, - "node_modules/ts-node": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", - "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", - "dev": true, - "dependencies": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" - }, - "bin": { - "ts-node": "dist/bin.js" - }, - "engines": { - "node": ">=4.2.0" - }, - "peerDependencies": { - "typescript": ">=2.0" - } - }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "node_modules/type-fest": { "version": "0.21.3", @@ -12510,15 +12472,6 @@ "node": ">=12" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/zone.js": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.8.tgz", @@ -12659,6 +12612,12 @@ "dev": true } } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true } } }, @@ -14719,9 +14678,9 @@ "dev": true }, "@types/node": { - "version": "18.11.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.0.tgz", - "integrity": "sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w==", + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", "dev": true }, "@types/parse-json": { @@ -15153,12 +15112,6 @@ "readable-stream": "^3.6.0" } }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -16095,12 +16048,6 @@ "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", "dev": true }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -18187,12 +18134,6 @@ } } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "make-fetch-happen": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", @@ -20975,23 +20916,10 @@ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, - "ts-node": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", - "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", - "dev": true, - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "^3.0.0" - } - }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "type-fest": { "version": "0.21.3", @@ -21518,12 +21446,6 @@ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - }, "zone.js": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.8.tgz", diff --git a/kdb-web/package.json b/kdb-web/package.json index c6c72b80e0..6fe001a630 100644 --- a/kdb-web/package.json +++ b/kdb-web/package.json @@ -1,6 +1,6 @@ { "name": "kdb-web", - "version": "0.3.0", + "version": "0.3.dev128", "scripts": { "ng": "ng", "update-version": "ts-node-esm update-version.ts", @@ -33,7 +33,6 @@ "primeng": "^14.1.2", "rxjs": "~7.5.0", "socket.io-client": "^4.5.3", - "tslib": "^2.3.0", "zone.js": "~0.11.4" }, "devDependencies": { @@ -41,13 +40,14 @@ "@angular/cli": "~14.0.0", "@angular/compiler-cli": "^14.0.0", "@types/jasmine": "~4.0.0", - "@types/node": "^18.8.3", + "@types/node": "^18.11.9", "jasmine-core": "~4.1.0", "karma": "~6.3.0", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.0.0", "karma-jasmine-html-reporter": "~1.7.0", + "tslib": "^2.4.1", "typescript": "~4.7.2" } } \ No newline at end of file diff --git a/kdb-web/src/app/modules/auth/components/login/login.component.html b/kdb-web/src/app/modules/auth/components/login/login.component.html index d6ee032619..d26ca6d40e 100644 --- a/kdb-web/src/app/modules/auth/components/login/login.component.html +++ b/kdb-web/src/app/modules/auth/components/login/login.component.html @@ -1,60 +1,65 @@
- - -
\ No newline at end of file + + diff --git a/kdb-web/src/app/modules/auth/components/login/login.component.ts b/kdb-web/src/app/modules/auth/components/login/login.component.ts index 4a073c9afb..8ab34cf990 100644 --- a/kdb-web/src/app/modules/auth/components/login/login.component.ts +++ b/kdb-web/src/app/modules/auth/components/login/login.component.ts @@ -1,20 +1,21 @@ -import { Component, OnInit } from '@angular/core'; -import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { AuthService } from 'src/app/services/auth/auth.service'; -import { AuthUserDTO } from 'src/app/models/auth/auth-user.dto'; -import { Router } from '@angular/router'; -import { catchError } from 'rxjs/operators'; -import { ErrorDTO } from 'src/app/models/error/error-dto'; -import { AuthErrorMessages } from 'src/app/models/auth/auth-error-messages.enum'; -import { ServiceErrorCode } from 'src/app/models/error/service-error-code.enum'; -import { AuthUserAtrErrors } from 'src/app/models/auth/auth-user-atr-errors'; -import { SpinnerService } from 'src/app/services/spinner/spinner.service'; -import { ThemeService } from 'src/app/services/theme/theme.service'; +import { Component, OnInit } from "@angular/core"; +import { FormBuilder, FormControl, FormGroup, Validators } from "@angular/forms"; +import { AuthService } from "src/app/services/auth/auth.service"; +import { AuthUserDTO } from "src/app/models/auth/auth-user.dto"; +import { ActivatedRoute, Router } from "@angular/router"; +import { catchError } from "rxjs/operators"; +import { ErrorDTO } from "src/app/models/error/error-dto"; +import { AuthErrorMessages } from "src/app/models/auth/auth-error-messages.enum"; +import { ServiceErrorCode } from "src/app/models/error/service-error-code.enum"; +import { AuthUserAtrErrors } from "src/app/models/auth/auth-user-atr-errors"; +import { SpinnerService } from "src/app/services/spinner/spinner.service"; +import { ThemeService } from "src/app/services/theme/theme.service"; +import { throwError } from "rxjs"; @Component({ - selector: 'app-login', - templateUrl: './login.component.html', - styleUrls: ['./login.component.scss'] + selector: "app-login", + templateUrl: "./login.component.html", + styleUrls: ["./login.component.scss"] }) export class LoginComponent implements OnInit { @@ -25,45 +26,83 @@ export class LoginComponent implements OnInit { submitted = false; authUserAtrErrors!: AuthUserAtrErrors; + code!: string; + state!: string; + user!: AuthUserDTO; + oAuthId!: string; constructor( private authService: AuthService, private formBuilder: FormBuilder, private router: Router, private spinnerService: SpinnerService, - private themeService: ThemeService - ) { } + private themeService: ThemeService, + private route: ActivatedRoute + ) { + } ngOnInit(): void { this.spinnerService.showSpinner(); this.authService.isUserLoggedInAsync().then(result => { if (result) { - this.router.navigate(['/dashboard']); + this.router.navigate(["/dashboard"]); + return; } + this.checkDiscordLogin(); this.initLoginForm(); this.resetStateFlags(); this.spinnerService.hideSpinner(); }); } + checkDiscordLogin() { + this.route.queryParams.pipe(catchError(err => { + this.spinnerService.hideSpinner(); + this.router.navigate(["auth", "login"]).then(() => { + }); + return throwError(() => err); + })).subscribe(params => { + if (!params["code"] || !params["state"]) { + this.spinnerService.hideSpinner(); + return; + } + + this.code = params["code"]; + this.state = params["state"]; + this.authService.discordLogin(this.code, this.state).pipe(catchError(err => { + this.spinnerService.hideSpinner(); + this.router.navigate(["auth", "login"]).then(() => { + }); + return throwError(() => err); + })).subscribe(token => { + this.authService.saveToken(token); + this.themeService.loadTheme(); + this.themeService.loadMenu(); + this.spinnerService.hideSpinner(); + this.router.navigate(["/dashboard"]); + }); + } + ); + } + resetStateFlags(): void { this.authUserAtrErrors = new AuthUserAtrErrors(); } initLoginForm(): void { this.loginForm = this.formBuilder.group({ - email: ['', [Validators.required, Validators.email]], - password: ['', [Validators.required, Validators.minLength(8)]] + email: ["", [Validators.required, Validators.email]], + password: ["", [Validators.required, Validators.minLength(8)]] }); } register(): void { - this.router.navigate(['/auth/register']); + this.router.navigate(["/auth/register"]); } forgotPassword(): void { - this.router.navigate(['/auth/forgot-password']); + this.router.navigate(["/auth/forgot-password"]); } login(): void { @@ -76,8 +115,8 @@ export class LoginComponent implements OnInit { this.spinnerService.showSpinner(); const user: AuthUserDTO = { - firstName: '', - lastName: '', + firstName: "", + lastName: "", email: this.loginForm.value.email ?? null, password: this.loginForm.value.password ?? null }; @@ -107,8 +146,14 @@ export class LoginComponent implements OnInit { this.themeService.loadTheme(); this.themeService.loadMenu(); this.spinnerService.hideSpinner(); - this.router.navigate(['/dashboard']); + this.router.navigate(["/dashboard"]); }); } + discordLogin() { + this.authService.getDiscordAuthURL().subscribe(url => { + window.location.href = url.loginUrl; + }); + } + } diff --git a/kdb-web/src/app/modules/auth/components/registration/registration.component.html b/kdb-web/src/app/modules/auth/components/registration/registration.component.html index 3433a400fd..11a154efff 100644 --- a/kdb-web/src/app/modules/auth/components/registration/registration.component.html +++ b/kdb-web/src/app/modules/auth/components/registration/registration.component.html @@ -72,12 +72,6 @@ [disabled]="loginForm.invalid"> -
- -
-