Finished Login / Register system
This commit is contained in:
15
.idea/.idea.WebDesktop 2.0/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
15
.idea/.idea.WebDesktop 2.0/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myValues">
|
||||||
|
<value>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="mat-input" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myCustomValuesEnabled" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
4
.idea/.idea.WebDesktop 2.0/.idea/watcherTasks.xml
generated
Normal file
4
.idea/.idea.WebDesktop 2.0/.idea/watcherTasks.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectTasksOptions" suppressed-tasks="SCSS" />
|
||||||
|
</project>
|
||||||
27
.idea/.idea.WebDesktop 2.0/.idea/workspace.xml
generated
27
.idea/.idea.WebDesktop 2.0/.idea/workspace.xml
generated
@@ -6,10 +6,30 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="041c7675-58ae-4243-af88-0d29855e558f" name="Changes" comment="">
|
<list default="true" id="041c7675-58ae-4243-af88-0d29855e558f" name="Changes" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.WebDesktop 2.0/.idea/vcs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.WebDesktop 2.0/.idea/vcs.xml" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/.idea/.idea.WebDesktop 2.0/.idea/inspectionProfiles/Project_Default.xml" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/.idea/.idea.WebDesktop 2.0/.idea/watcherTasks.xml" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Frontend/src/app/sites/register/register.component.html" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Frontend/src/app/sites/register/register.component.scss" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Frontend/src/app/sites/register/register.component.ts" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Frontend/src/assets/background.png" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Frontend/src/colors.scss" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.WebDesktop 2.0/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.WebDesktop 2.0/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/.idea.WebDesktop 2.0/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.WebDesktop 2.0/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Backend/Controllers/UserController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Backend/Controllers/UserController.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Backend/Controllers/UserController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Backend/Controllers/UserController.cs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Backend/Security/Permissions.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Backend/Security/Permissions.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Backend/appsettings.json" beforeDir="false" afterPath="$PROJECT_DIR$/Backend/appsettings.json" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/angular.json" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/angular.json" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/package-lock.json" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/package.json" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/app/app-routing.module.ts" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/app/app-routing.module.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/app/app.component.ts" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/app/app.component.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/app/app.module.ts" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/app/app.module.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/app/entitys/user.ts" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/app/entitys/user.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/app/services/backend.service.ts" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/app/services/backend.service.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/app/services/users.service.ts" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/app/services/users.service.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/app/sites/login/login.component.html" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/app/sites/login/login.component.html" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/app/sites/login/login.component.scss" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/app/sites/login/login.component.scss" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/app/sites/login/login.component.ts" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/app/sites/login/login.component.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/index.html" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Frontend/src/styles.scss" beforeDir="false" afterPath="$PROJECT_DIR$/Frontend/src/styles.scss" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -20,6 +40,7 @@
|
|||||||
<option name="RECENT_TEMPLATES">
|
<option name="RECENT_TEMPLATES">
|
||||||
<list>
|
<list>
|
||||||
<option value="TypeScript File" />
|
<option value="TypeScript File" />
|
||||||
|
<option value="SCSS File" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
@@ -48,6 +69,7 @@
|
|||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
"WebServerToolWindowFactoryState": "false",
|
"WebServerToolWindowFactoryState": "false",
|
||||||
|
"list.type.of.created.stylesheet": "SCSS",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"settings.editor.selected.configurable": "project.propVCSSupport.DirectoryMappings",
|
"settings.editor.selected.configurable": "project.propVCSSupport.DirectoryMappings",
|
||||||
"ts.external.directory.path": "D:\\Programmierstuff\\Projekte\\WebDesktop 2.0\\Frontend\\node_modules\\typescript\\lib",
|
"ts.external.directory.path": "D:\\Programmierstuff\\Projekte\\WebDesktop 2.0\\Frontend\\node_modules\\typescript\\lib",
|
||||||
@@ -130,6 +152,7 @@
|
|||||||
<workItem from="1662126115999" duration="9904000" />
|
<workItem from="1662126115999" duration="9904000" />
|
||||||
<workItem from="1662204907636" duration="15449000" />
|
<workItem from="1662204907636" duration="15449000" />
|
||||||
<workItem from="1662228779224" duration="302000" />
|
<workItem from="1662228779224" duration="302000" />
|
||||||
|
<workItem from="1662539031966" duration="6394000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ public class UserController : ControllerBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("token")]
|
[HttpGet("token")]
|
||||||
[Authorized]
|
|
||||||
public ActionResult<AccessToken> GetToken() {
|
public ActionResult<AccessToken> GetToken() {
|
||||||
return this.FromLogicResult(_logic.GenerateToken(_logic.GetCurrentUserRefreshToken()));
|
return this.FromLogicResult(_logic.GenerateToken(_logic.GetCurrentUserRefreshToken()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,12 +33,12 @@
|
|||||||
],
|
],
|
||||||
"Messages": {
|
"Messages": {
|
||||||
"Users": {
|
"Users": {
|
||||||
"NotFound": "This user does not exist",
|
"NotFound": "Dieser Benutzer existiert nicht!",
|
||||||
"InvalidEditData": "Userdata does not match security rules",
|
"InvalidEditData": "Benutzerdaten entsprechen nicht den Sicherheitsvorschritfen!",
|
||||||
"InvalidRegisterData": "Userdata does not match security rules",
|
"InvalidRegisterData": "Benutzerdaten entsprechen nicht den Sicherheitsvorschritfen!",
|
||||||
"WrongPassword": "Wrong password",
|
"WrongPassword": "Falsches Passwort!",
|
||||||
"UsernameOrEmailExist": "This username or email already exist",
|
"UsernameOrEmailExist": "Der Benutzername oder die E-Mail existieren bereits",
|
||||||
"InvalidRefreshToken": "Invalid RefreshToken"
|
"InvalidRefreshToken": "Dein RefreshToken ist abgelaufen!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
|
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
@@ -99,6 +100,7 @@
|
|||||||
"src/assets"
|
"src/assets"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
|
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
||||||
"src/styles.scss"
|
"src/styles.scss"
|
||||||
],
|
],
|
||||||
"scripts": []
|
"scripts": []
|
||||||
|
|||||||
66
Frontend/package-lock.json
generated
66
Frontend/package-lock.json
generated
@@ -9,10 +9,12 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "~13.1.0",
|
"@angular/animations": "~13.1.0",
|
||||||
|
"@angular/cdk": "^13.3.9",
|
||||||
"@angular/common": "~13.1.0",
|
"@angular/common": "~13.1.0",
|
||||||
"@angular/compiler": "~13.1.0",
|
"@angular/compiler": "~13.1.0",
|
||||||
"@angular/core": "~13.1.0",
|
"@angular/core": "~13.1.0",
|
||||||
"@angular/forms": "~13.1.0",
|
"@angular/forms": "~13.1.0",
|
||||||
|
"@angular/material": "^13.3.9",
|
||||||
"@angular/platform-browser": "~13.1.0",
|
"@angular/platform-browser": "~13.1.0",
|
||||||
"@angular/platform-browser-dynamic": "~13.1.0",
|
"@angular/platform-browser-dynamic": "~13.1.0",
|
||||||
"@angular/router": "~13.1.0",
|
"@angular/router": "~13.1.0",
|
||||||
@@ -347,6 +349,28 @@
|
|||||||
"@angular/core": "13.1.3"
|
"@angular/core": "13.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@angular/cdk": {
|
||||||
|
"version": "13.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.3.9.tgz",
|
||||||
|
"integrity": "sha512-XCuCbeuxWFyo3EYrgEYx7eHzwl76vaWcxtWXl00ka8d+WAOtMQ6Tf1D98ybYT5uwF9889fFpXAPw98mVnlo3MA==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"parse5": "^5.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": "^13.0.0 || ^14.0.0-0",
|
||||||
|
"@angular/core": "^13.0.0 || ^14.0.0-0",
|
||||||
|
"rxjs": "^6.5.3 || ^7.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@angular/cdk/node_modules/parse5": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/@angular/cli": {
|
"node_modules/@angular/cli": {
|
||||||
"version": "13.1.4",
|
"version": "13.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.1.4.tgz",
|
||||||
@@ -472,6 +496,23 @@
|
|||||||
"rxjs": "^6.5.3 || ^7.4.0"
|
"rxjs": "^6.5.3 || ^7.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@angular/material": {
|
||||||
|
"version": "13.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/material/-/material-13.3.9.tgz",
|
||||||
|
"integrity": "sha512-FU8lcMgo+AL8ckd27B4V097ZPoIZNRHiCe3wpgkImT1qC0YwcyXZVn0MqQTTFSdC9a/aI8wPm3AbTClJEVw5Vw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/animations": "^13.0.0 || ^14.0.0-0",
|
||||||
|
"@angular/cdk": "13.3.9",
|
||||||
|
"@angular/common": "^13.0.0 || ^14.0.0-0",
|
||||||
|
"@angular/core": "^13.0.0 || ^14.0.0-0",
|
||||||
|
"@angular/forms": "^13.0.0 || ^14.0.0-0",
|
||||||
|
"@angular/platform-browser": "^13.0.0 || ^14.0.0-0",
|
||||||
|
"rxjs": "^6.5.3 || ^7.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@angular/platform-browser": {
|
"node_modules/@angular/platform-browser": {
|
||||||
"version": "13.1.3",
|
"version": "13.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.1.3.tgz",
|
||||||
@@ -11779,6 +11820,23 @@
|
|||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@angular/cdk": {
|
||||||
|
"version": "13.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-13.3.9.tgz",
|
||||||
|
"integrity": "sha512-XCuCbeuxWFyo3EYrgEYx7eHzwl76vaWcxtWXl00ka8d+WAOtMQ6Tf1D98ybYT5uwF9889fFpXAPw98mVnlo3MA==",
|
||||||
|
"requires": {
|
||||||
|
"parse5": "^5.0.0",
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"parse5": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@angular/cli": {
|
"@angular/cli": {
|
||||||
"version": "13.1.4",
|
"version": "13.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.1.4.tgz",
|
||||||
@@ -11857,6 +11915,14 @@
|
|||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@angular/material": {
|
||||||
|
"version": "13.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular/material/-/material-13.3.9.tgz",
|
||||||
|
"integrity": "sha512-FU8lcMgo+AL8ckd27B4V097ZPoIZNRHiCe3wpgkImT1qC0YwcyXZVn0MqQTTFSdC9a/aI8wPm3AbTClJEVw5Vw==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@angular/platform-browser": {
|
"@angular/platform-browser": {
|
||||||
"version": "13.1.3",
|
"version": "13.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.1.3.tgz",
|
||||||
|
|||||||
@@ -11,10 +11,12 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "~13.1.0",
|
"@angular/animations": "~13.1.0",
|
||||||
|
"@angular/cdk": "^13.3.9",
|
||||||
"@angular/common": "~13.1.0",
|
"@angular/common": "~13.1.0",
|
||||||
"@angular/compiler": "~13.1.0",
|
"@angular/compiler": "~13.1.0",
|
||||||
"@angular/core": "~13.1.0",
|
"@angular/core": "~13.1.0",
|
||||||
"@angular/forms": "~13.1.0",
|
"@angular/forms": "~13.1.0",
|
||||||
|
"@angular/material": "^13.3.9",
|
||||||
"@angular/platform-browser": "~13.1.0",
|
"@angular/platform-browser": "~13.1.0",
|
||||||
"@angular/platform-browser-dynamic": "~13.1.0",
|
"@angular/platform-browser-dynamic": "~13.1.0",
|
||||||
"@angular/router": "~13.1.0",
|
"@angular/router": "~13.1.0",
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
import {LoginComponent} from "./sites/login/login.component";
|
import {LoginComponent} from "./sites/login/login.component";
|
||||||
|
import {RegisterComponent} from "./sites/register/register.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{path: "login", component: LoginComponent}
|
{path: "login", component: LoginComponent},
|
||||||
|
{path: "register", component: RegisterComponent}
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export class AppComponent implements OnInit {
|
|||||||
|
|
||||||
if (await this.backend.requestToken()) this.loaded = true;
|
if (await this.backend.requestToken()) this.loaded = true;
|
||||||
else await this.router.navigate(["login"]);
|
else await this.router.navigate(["login"]);
|
||||||
|
this.loaded = true;
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,16 +5,30 @@ import { AppRoutingModule } from './app-routing.module';
|
|||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import {HttpClientModule} from "@angular/common/http";
|
import {HttpClientModule} from "@angular/common/http";
|
||||||
import { LoginComponent } from './sites/login/login.component';
|
import { LoginComponent } from './sites/login/login.component';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import {MatFormFieldModule} from "@angular/material/form-field";
|
||||||
|
import {MatInputModule} from "@angular/material/input";
|
||||||
|
import {MatButtonModule} from "@angular/material/button";
|
||||||
|
import {MatDividerModule} from "@angular/material/divider";
|
||||||
|
import { RegisterComponent } from './sites/register/register.component';
|
||||||
|
import {ReactiveFormsModule} from "@angular/forms";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
LoginComponent
|
LoginComponent,
|
||||||
|
RegisterComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
HttpClientModule
|
HttpClientModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatButtonModule,
|
||||||
|
MatDividerModule,
|
||||||
|
ReactiveFormsModule
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export interface User extends UserEditor {
|
export interface User extends UserEditor {
|
||||||
id: string;
|
id: string;
|
||||||
created: Date;
|
created: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserLogin {
|
export interface UserLogin {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export class BackendService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {content: undefined, success: false, code: error.status, message: error.error.title};
|
return {content: undefined, success: false, code: error.status, message: error.error};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ export class UserApi {
|
|||||||
return response.success;
|
return response.success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getUserPermissions(id: string, includeGroupPermissions: boolean = true): Promise<string[]> {
|
public async getUserPermissions(id: string, excludeGroupPermissions: boolean = false): Promise<string[]> {
|
||||||
const response = await this.backend.sendRequest<string[]>(RequestTypes.GET, "users/" + id + "/permissions" + (includeGroupPermissions ? "/raw" : ""), undefined, {authorized: true});
|
const response = await this.backend.sendRequest<string[]>(RequestTypes.GET, "users/" + id + "/permissions" + (excludeGroupPermissions ? "/raw" : ""), undefined, {authorized: true});
|
||||||
if (!response.success) return [];
|
if (!response.success) return [];
|
||||||
return response.content;
|
return response.content;
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ export class UserApi {
|
|||||||
return response.success;
|
return response.success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async login(login: UserLogin): Promise<{success: boolean, errorMessage: string}> {
|
public async login(login: UserLogin): Promise<{success: boolean, errorMessage: string, errorCode: number}> {
|
||||||
const response = await this.backend.sendRequest<AccessToken>(RequestTypes.PUT, "users/login", login, {withCredentials: true});
|
const response = await this.backend.sendRequest<AccessToken>(RequestTypes.PUT, "users/login", login, {withCredentials: true});
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
@@ -56,10 +56,10 @@ export class UserApi {
|
|||||||
await this.getAuthorizedUser();
|
await this.getAuthorizedUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {success: response.success, errorMessage: response.message};
|
return {success: response.success, errorMessage: response.message, errorCode: response.code};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async register(register: UserEditor): Promise<{success: boolean, errorMessage: string}> {
|
public async register(register: UserEditor): Promise<{success: boolean, errorMessage: string, errorCode: number}> {
|
||||||
const response = await this.backend.sendRequest<AccessToken>(RequestTypes.POST, "users/register", register, {withCredentials: true});
|
const response = await this.backend.sendRequest<AccessToken>(RequestTypes.POST, "users/register", register, {withCredentials: true});
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
@@ -67,7 +67,7 @@ export class UserApi {
|
|||||||
await this.getAuthorizedUser();
|
await this.getAuthorizedUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {success: response.success, errorMessage: response.message};
|
return {success: response.success, errorMessage: response.message, errorCode: response.code};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async logout(id: string): Promise<boolean> {
|
public async logout(id: string): Promise<boolean> {
|
||||||
|
|||||||
@@ -1 +1,24 @@
|
|||||||
<p>login works!</p>
|
<section class="login">
|
||||||
|
<form class="glass" (submit)="$event.preventDefault(); login(form, username.value, password.value)" #form>
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>Benutzername oder E-Mail</mat-label>
|
||||||
|
<input matInput type="text" required #username>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>Passwort</mat-label>
|
||||||
|
<input matInput type="password" required #password>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<button mat-button type="submit" [disabled]="disableLogin">Einloggen</button>
|
||||||
|
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span>Du besitzt keinen Account? </span>
|
||||||
|
<a routerLink="/register">Registrieren</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="error" #error></div>
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
@use "src/styles";
|
||||||
|
|
||||||
|
.login {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
background-image: url(styles.$background);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
form {
|
||||||
|
padding: 30px;
|
||||||
|
display: flex;
|
||||||
|
gap: 5px;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
width: max-content;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-divider {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 120px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
|
||||||
|
background-color: #F00;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
transition: 500ms;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,15 +1,45 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import {Component, ElementRef, ViewChild} from '@angular/core';
|
||||||
|
import {UserApi} from "../../services/users.service";
|
||||||
|
import {UserLogin} from "../../entitys/user";
|
||||||
|
import {Router} from "@angular/router";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-login',
|
selector: 'app-login',
|
||||||
templateUrl: './login.component.html',
|
templateUrl: './login.component.html',
|
||||||
styleUrls: ['./login.component.scss']
|
styleUrls: ['./login.component.scss']
|
||||||
})
|
})
|
||||||
export class LoginComponent implements OnInit {
|
export class LoginComponent {
|
||||||
|
@ViewChild('error') error: ElementRef;
|
||||||
|
public disableLogin: boolean = false;
|
||||||
|
|
||||||
constructor() { }
|
constructor(private users: UserApi, private router: Router) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
public async login(form: HTMLFormElement, username: string, password: string) {
|
||||||
|
if (!form.reportValidity()) return;
|
||||||
|
|
||||||
|
const login: UserLogin = {usernameOrEmail: username, password: password};
|
||||||
|
const response = await this.users.login(login);
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
this.showError(response.errorMessage)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.router.navigate([""]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public showError(error: string) {
|
||||||
|
this.disableLogin = true;
|
||||||
|
this.error.nativeElement.innerText = error;
|
||||||
|
|
||||||
|
this.error.nativeElement.style.opacity = "1";
|
||||||
|
this.error.nativeElement.style.bottom = "150px";
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.error.nativeElement.style.opacity = "0";
|
||||||
|
this.error.nativeElement.style.bottom = "120px";
|
||||||
|
this.disableLogin = false;
|
||||||
|
}, 5000)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
57
Frontend/src/app/sites/register/register.component.html
Normal file
57
Frontend/src/app/sites/register/register.component.html
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<section class="login">
|
||||||
|
<form class="glass" (submit)="$event.preventDefault(); register(form, {
|
||||||
|
username: username.value,
|
||||||
|
password: password.value,
|
||||||
|
firstName: firstname.value,
|
||||||
|
lastName: lastname.value,
|
||||||
|
email: email.value
|
||||||
|
}, pwRepeat.value)" #form>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>Vorname</mat-label>
|
||||||
|
<input matInput type="text" required #firstname>
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>Nachname</mat-label>
|
||||||
|
<input matInput type="text" required #lastname>
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>Benutzername</mat-label>
|
||||||
|
<input matInput type="text" required #username>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>E-Mail</mat-label>
|
||||||
|
<input matInput type="email" required #email>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>Passwort</mat-label>
|
||||||
|
<input matInput type="password" required #password>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>Passwort wiederholen</mat-label>
|
||||||
|
<input matInput type="password" required #pwRepeat>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<button mat-button [disabled]="disableRegister" type="submit">Registrieren</button>
|
||||||
|
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span>Du hast bereits einen Account? </span>
|
||||||
|
<a routerLink="/login">Einloggen</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="error" #error></div>
|
||||||
42
Frontend/src/app/sites/register/register.component.scss
Normal file
42
Frontend/src/app/sites/register/register.component.scss
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
@use "src/styles";
|
||||||
|
|
||||||
|
.login {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
background-image: url(styles.$background);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
form {
|
||||||
|
padding: 30px;
|
||||||
|
display: flex;
|
||||||
|
gap: 5px;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
width: max-content;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-divider {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 120px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
|
||||||
|
background-color: #F00;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
transition: 500ms;
|
||||||
|
}
|
||||||
64
Frontend/src/app/sites/register/register.component.ts
Normal file
64
Frontend/src/app/sites/register/register.component.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import {Component, ElementRef, ViewChild} from '@angular/core';
|
||||||
|
import {UserApi} from "../../services/users.service";
|
||||||
|
import {Router} from "@angular/router";
|
||||||
|
import {UserEditor} from "../../entitys/user";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-register',
|
||||||
|
templateUrl: './register.component.html',
|
||||||
|
styleUrls: ['./register.component.scss']
|
||||||
|
})
|
||||||
|
export class RegisterComponent {
|
||||||
|
@ViewChild('error') error: ElementRef;
|
||||||
|
public disableRegister: boolean = false;
|
||||||
|
|
||||||
|
constructor(private users: UserApi, private router: Router) { }
|
||||||
|
|
||||||
|
public async register(form: HTMLFormElement, register: UserEditor, pwRepeat: string) {
|
||||||
|
if (!form.reportValidity()) return;
|
||||||
|
|
||||||
|
if (register.password !== pwRepeat) {
|
||||||
|
this.showError("Passwörter stimmen nicht überein!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!register.email.includes("@") || !register.email.includes(".")) {
|
||||||
|
this.showError("Bitte gebe eine gültige E-Mail Adresse ein!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (register.username.includes("@")) {
|
||||||
|
this.showError("Benutzername enthätlt ungültige Zeichen!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (register.password.length < 8) {
|
||||||
|
this.showError("Dein Passwort muss mindestens 8 Zeichen lang sein!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await this.users.register(register);
|
||||||
|
|
||||||
|
if (!response.success) {
|
||||||
|
this.showError(response.errorMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.router.navigate([""]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public showError(error: string) {
|
||||||
|
this.disableRegister = true;
|
||||||
|
this.error.nativeElement.innerText = error;
|
||||||
|
|
||||||
|
this.error.nativeElement.style.opacity = "1";
|
||||||
|
this.error.nativeElement.style.bottom = "150px";
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.error.nativeElement.style.opacity = "0";
|
||||||
|
this.error.nativeElement.style.bottom = "120px";
|
||||||
|
this.disableRegister = false;
|
||||||
|
}, 5000)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
BIN
Frontend/src/assets/background.png
Normal file
BIN
Frontend/src/assets/background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
4
Frontend/src/colors.scss
Normal file
4
Frontend/src/colors.scss
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
$dark: #0D1321;
|
||||||
|
$medium: #1D2D44;
|
||||||
|
$light: #3E5C76;
|
||||||
|
$text: #FFFFFF;
|
||||||
@@ -6,8 +6,11 @@
|
|||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="mat-typography">
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1 +1,31 @@
|
|||||||
/* You can add global styles to this file, and also import other style files */
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
@use "colors";
|
||||||
|
|
||||||
|
html, body { height: 100%; overflow: hidden; }
|
||||||
|
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
||||||
|
|
||||||
|
$background: "/assets/background.png";
|
||||||
|
|
||||||
|
* {
|
||||||
|
color: colors.$text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.glass {
|
||||||
|
background: rgba(colors.$light, 0.15);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border-radius: 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin mat-select-theme() {
|
||||||
|
.mat-form-field-appearance-fill .mat-form-field-underline::before {
|
||||||
|
background-color: colors.$text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-divider {
|
||||||
|
border-top-color: colors.$text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include mat-select-theme();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user