0.3 #146

Merged
edraft merged 359 commits from 0.3 into master 2023-01-12 07:04:40 +01:00
13 changed files with 210 additions and 295 deletions
Showing only changes of commit bd94c42eae - Show all commits

View File

@ -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

View File

@ -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())

View File

@ -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')

View File

@ -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",

View File

@ -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"
}
}

View File

@ -1,60 +1,65 @@
<section class="login-wrapper">
<div class="login-form-wrapper">
<div class="login-form">
<form [formGroup]="loginForm">
<h1>{{'auth.header' | translate}}</h1>
<div class="input-field">
<input type="email" pInputText formControlName="email" placeholder="{{'auth.login.e_mail' | translate}}" [ngClass]="{ 'invalid-feedback-input': submitted && (
<div class="login-form-wrapper">
<div class="login-form">
<form [formGroup]="loginForm">
<h1>{{'auth.header' | translate}}</h1>
<div class="input-field">
<input type="email" pInputText formControlName="email" placeholder="{{'auth.login.e_mail' | translate}}" [ngClass]="{ 'invalid-feedback-input': submitted && (
(loginForm.controls.email.errors && loginForm.controls.email.errors['required'] || authUserAtrErrors.email.required) ||
(authUserAtrErrors.email.wrongData) ||
(authUserAtrErrors.email.notConfirmed)
)}" autocomplete="username email">
<div *ngIf="submitted" class="invalid-feedback">
<div
*ngIf="loginForm.controls.email.errors && loginForm.controls.email.errors['required'] || authUserAtrErrors.email.required">
{{'auth.login.e_mail_required' | translate}}</div>
<div *ngIf="authUserAtrErrors.email.wrongData">{{'auth.login.user_not_found' | translate}}</div>
<div *ngIf="authUserAtrErrors.email.notConfirmed">{{'auth.login.e_mail_not_confirmed' | translate}}</div>
</div>
</div>
<div class="input-field">
<!--
!! WARNING !!
Bugfix from https://github.com/primefaces/primeng/issues/10788
styleClass="p-password p-component p-inputwrapper p-input-icon-right"
Remove after update!
-->
<p-password type="password" formControlName="password" placeholder="{{'auth.login.password' | translate}}" [ngClass]="{ 'invalid-feedback-input': submitted && (
<div *ngIf="submitted" class="invalid-feedback">
<div
*ngIf="loginForm.controls.email.errors && loginForm.controls.email.errors['required'] || authUserAtrErrors.email.required">
{{'auth.login.e_mail_required' | translate}}</div>
<div *ngIf="authUserAtrErrors.email.wrongData">{{'auth.login.user_not_found' | translate}}</div>
<div *ngIf="authUserAtrErrors.email.notConfirmed">{{'auth.login.e_mail_not_confirmed' | translate}}</div>
</div>
</div>
<div class="input-field">
<!--
!! WARNING !!
Bugfix from https://github.com/primefaces/primeng/issues/10788
styleClass="p-password p-component p-inputwrapper p-input-icon-right"
Remove after update!
-->
<p-password type="password" formControlName="password" placeholder="{{'auth.login.password' | translate}}" [ngClass]="{ 'invalid-feedback-input': submitted && (
(loginForm.controls.password.errors && loginForm.controls.password.errors['required'] || authUserAtrErrors.password.required) ||
(authUserAtrErrors.password.wrongData)
)}" autocomplete="current-password" [toggleMask]="true" [feedback]="false"
styleClass="p-password p-component p-inputwrapper p-input-icon-right"
></p-password>
<div *ngIf="submitted" class="invalid-feedback">
<div
*ngIf="loginForm.controls.password.errors && loginForm.controls.password.errors['required'] || authUserAtrErrors.password.required">
{{'auth.login.password_required' | translate}}</div>
<div *ngIf="authUserAtrErrors.password.wrongData">{{'auth.login.wrong_password' | translate}}</div>
</div>
</div>
<div class="login-form-submit">
<button pButton label="{{'auth.login.login' | translate}}" class="btn login-form-submit-btn" (click)="login()"
[disabled]="loginForm.invalid"></button>
</div>
<div class="login-form-sub-button-wrapper">
<div class="login-form-sub-btn-wrapper">
<button pButton label="{{'auth.login.register' | translate}}" class="btn login-form-sub-btn"
(click)="register()"></button>
</div>
<div class="login-form-sub-btn-wrapper">
<button pButton label="{{'auth.login.forgot_password' | translate}}"
class="btn login-form-sub-btn login-form-sub-login-btn p-button-text"
(click)="forgotPassword()"></button>
</div>
</div>
</form>
styleClass="p-password p-component p-inputwrapper p-input-icon-right"
></p-password>
<div *ngIf="submitted" class="invalid-feedback">
<div
*ngIf="loginForm.controls.password.errors && loginForm.controls.password.errors['required'] || authUserAtrErrors.password.required">
{{'auth.login.password_required' | translate}}</div>
<div *ngIf="authUserAtrErrors.password.wrongData">{{'auth.login.wrong_password' | translate}}</div>
</div>
</div>
<div class="login-form-submit">
<button pButton label="{{'auth.login.login' | translate}}" class="btn login-form-submit-btn" (click)="login()"
[disabled]="loginForm.invalid"></button>
</div>
<div class="login-form-sub-button-wrapper" *ngIf="!code && !state">
<div class="login-form-sub-btn-wrapper">
<button pButton label="{{'auth.login.login_with_discord' | translate}}" class="btn login-form-sub-btn" (click)="discordLogin()"></button>
</div>
</div>
<div class="login-form-sub-button-wrapper">
<div class="login-form-sub-btn-wrapper">
<button pButton label="{{'auth.login.register' | translate}}" class="btn login-form-sub-btn"
(click)="register()"></button>
</div>
<div class="login-form-sub-btn-wrapper">
<button pButton label="{{'auth.login.forgot_password' | translate}}"
class="btn login-form-sub-btn login-form-sub-login-btn p-button-text"
(click)="forgotPassword()"></button>
</div>
</div>
</form>
</div>
</div>
<app-auth-header></app-auth-header>
</section>
<app-auth-header></app-auth-header>
</section>

View File

@ -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;
});
}
}

View File

@ -72,12 +72,6 @@
[disabled]="loginForm.invalid"></button>
</div>
<div class="login-form-sub-button-wrapper" *ngIf="!code && !state">
<div class="login-form-sub-btn-wrapper">
<button pButton label="{{'auth.register.register_with_discord' | translate}}" class="btn login-form-sub-btn" (click)="discordLogin()"></button>
</div>
</div>
<div class="login-form-sub-button-wrapper">
<div class="login-form-sub-btn-wrapper">
<button pButton label="{{'auth.register.login' | translate}}" class="btn login-form-sub-btn" (click)="login()"></button>

View File

@ -34,14 +34,6 @@ export class RegistrationComponent implements OnInit {
password: false
};
showEMailConfirmation = false;
showEMailConfirmationError = false;
code!: string;
state!: string;
user!: AuthUserDTO;
oAuthId!: string;
constructor(
private authService: AuthService,
private formBuilder: FormBuilder,
@ -62,48 +54,7 @@ export class RegistrationComponent implements OnInit {
this.confirmEMail();
this.initData();
this.spinnerService.showSpinner();
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;
}
if (this.user) {
this.spinnerService.hideSpinner();
return;
}
this.code = params["code"];
this.state = params["state"];
this.authService.discordCreateUser(this.code, this.state).pipe(catchError(err => {
this.spinnerService.hideSpinner();
this.router.navigate(["auth", "login"]).then(() => {
});
return throwError(() => err);
})).subscribe(oAuthDTO => {
if (oAuthDTO) {
this.user = oAuthDTO.user;
this.oAuthId = oAuthDTO.oAuthId;
}
if (this.user && !this.oAuthId) {
this.router.navigate(["auth", "login"]).then(() => {
});
return;
}
this.router.navigate(["auth", "register"]).then(() => {
});
this.initData();
}
);
this.initData();
}
);
this.initData();
}
initData() {
@ -126,18 +77,13 @@ export class RegistrationComponent implements OnInit {
initLoginForm(): void {
this.loginForm = this.formBuilder.group({
firstName: [this.user ? this.user.firstName : "", Validators.required],
lastName: [this.user ? this.user.lastName : "", Validators.required],
email: [this.user ? this.user.email : "", [Validators.required, Validators.email]],
emailRepeat: [this.user ? this.user.email : "", [Validators.required, Validators.email]],
password: [this.user ? this.user.password : "", [Validators.required, Validators.minLength(8)]],
passwordRepeat: [this.user ? this.user.password : "", [Validators.required, Validators.minLength(8)]]
firstName: ["", Validators.required],
lastName: ["", Validators.required],
email: ["", [Validators.required, Validators.email]],
emailRepeat: ["", [Validators.required, Validators.email]],
password: ["", [Validators.required, Validators.minLength(8)]],
passwordRepeat: ["", [Validators.required, Validators.minLength(8)]]
});
if (this.user) {
this.loginForm.controls.email.disable();
this.loginForm.controls.emailRepeat.disable();
}
}
register(): void {
@ -160,42 +106,10 @@ export class RegistrationComponent implements OnInit {
}
this.spinnerService.showSpinner();
if (this.user && this.oAuthId) {
this.registerWithOAuth();
return;
}
this.registerLocal();
}
private registerWithOAuth() {
const oAuthDTO: OAuthDTO = {
user: {
firstName: this.loginForm.value.firstName ?? this.user.firstName,
lastName: this.loginForm.value.lastName ?? this.user.lastName,
email: this.loginForm.value.email ?? this.user.email,
password: this.loginForm.value.password ?? null
},
oAuthId: this.oAuthId
};
this.authService.discordRegister(oAuthDTO)
.pipe(catchError(error => {
if (error.error !== null) {
const err: ErrorDTO = error.error;
if (err.errorCode === ServiceErrorCode.InvalidUser && err.message === AuthErrorMessages.UserAlreadyExists) {
this.authUserAtrErrors.email.wrongData = true;
}
}
this.spinnerService.hideSpinner();
throw error;
}))
.subscribe(resp => {
this.spinnerService.hideSpinner();
this.router.navigate(["/auth/login"]);
});
}
private registerLocal() {
const user: AuthUserDTO = {
firstName: this.loginForm.value.firstName ?? null,
@ -237,10 +151,4 @@ export class RegistrationComponent implements OnInit {
});
}
}
discordLogin() {
this.authService.getDiscordAuthURL().subscribe(url => {
window.location.href = url.loginUrl;
});
}
}

View File

@ -167,6 +167,7 @@ export class AuthService {
})
});
}
discordCreateUser(code: string, state: string) {
return this.http.get<OAuthDTO>(`${this.appsettings.getApiURL()}/api/auth/discord/create-user?code=${code}&state=${state}`, {
headers: new HttpHeaders({
@ -175,6 +176,14 @@ export class AuthService {
});
}
discordLogin(code: string, state: string): Observable<TokenDTO> {
return this.http.get<TokenDTO>(`${this.appsettings.getApiURL()}/api/auth/discord/login?code=${code}&state=${state}`, {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
});
}
// /api/auth/discord/register?code=
discordRegister(oAuthDTO: OAuthDTO) {
return this.http.post(`${this.appsettings.getApiURL()}/api/auth/discord/register`, oAuthDTO, {

View File

@ -3,7 +3,7 @@
"WebVersion": {
"Major": "0",
"Minor": "3",
"Micro": "dev70"
"Micro": "dev128"
},
"Themes": [
{

View File

@ -93,6 +93,7 @@
"e_mail": "E-Mail",
"password": "Passwort",
"login": "Einloggen",
"login_with_discord": "Mit Discord Einloggen",
"register": "Registrieren",
"forgot_password": "Passwort vergessen?",
"e_mail_required": "E-Mail benötigt",

View File

@ -373,7 +373,7 @@ footer {
.login-form-wrapper,
.auth-header {
width: 350px;
height: 350px;
height: 450px;
display: flex;
justify-content: center;