Compare commits
No commits in common. "b14a4a38a0118d7e9ce00f2849eadf483f08251a" and "0be5c36194a5b59cf56bb0c7e649bf04a3100afe" have entirely different histories.
b14a4a38a0
...
0be5c36194
|
@ -28,9 +28,6 @@
|
|||
"@angular/platform-browser": "^17.3.0",
|
||||
"@angular/platform-browser-dynamic": "^17.3.0",
|
||||
"@angular/router": "^17.3.0",
|
||||
"@types/dompurify": "^3.0.5",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dompurify": "^3.1.3",
|
||||
"primeng": "^17.11.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
|
@ -48,7 +45,6 @@
|
|||
"@stylistic/eslint-plugin": "^2.1.0",
|
||||
"@stylistic/eslint-plugin-migrate": "^2.1.0",
|
||||
"@stylistic/eslint-plugin-ts": "^2.1.0",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@typescript-eslint/eslint-plugin": "6.19.0",
|
||||
"@typescript-eslint/parser": "6.19.0",
|
||||
|
|
|
@ -29,15 +29,6 @@ dependencies:
|
|||
'@angular/router':
|
||||
specifier: ^17.3.0
|
||||
version: 17.3.0(@angular/common@17.3.0)(@angular/core@17.3.0)(@angular/platform-browser@17.3.0)(rxjs@7.8.1)
|
||||
'@types/dompurify':
|
||||
specifier: ^3.0.5
|
||||
version: 3.0.5
|
||||
crypto-js:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0
|
||||
dompurify:
|
||||
specifier: ^3.1.3
|
||||
version: 3.1.3
|
||||
primeng:
|
||||
specifier: ^17.11.0
|
||||
version: 17.11.0(@angular/common@17.3.0)(@angular/core@17.3.0)(@angular/forms@17.3.0)(rxjs@7.8.1)(zone.js@0.14.4)
|
||||
|
@ -85,9 +76,6 @@ devDependencies:
|
|||
'@stylistic/eslint-plugin-ts':
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0(eslint@8.57.0)(typescript@5.4.2)
|
||||
'@types/crypto-js':
|
||||
specifier: ^4.2.2
|
||||
version: 4.2.2
|
||||
'@types/jest':
|
||||
specifier: ^29.5.12
|
||||
version: 29.5.12
|
||||
|
@ -3243,16 +3231,6 @@ packages:
|
|||
'@types/node': 20.11.27
|
||||
dev: true
|
||||
|
||||
/@types/crypto-js@4.2.2:
|
||||
resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==}
|
||||
dev: true
|
||||
|
||||
/@types/dompurify@3.0.5:
|
||||
resolution: {integrity: sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==}
|
||||
dependencies:
|
||||
'@types/trusted-types': 2.0.7
|
||||
dev: false
|
||||
|
||||
/@types/eslint-scope@3.7.7:
|
||||
resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
|
||||
dependencies:
|
||||
|
@ -3422,10 +3400,6 @@ packages:
|
|||
resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
|
||||
dev: true
|
||||
|
||||
/@types/trusted-types@2.0.7:
|
||||
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||
dev: false
|
||||
|
||||
/@types/ws@8.5.10:
|
||||
resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
|
||||
dependencies:
|
||||
|
@ -4736,10 +4710,6 @@ packages:
|
|||
which: 2.0.2
|
||||
dev: true
|
||||
|
||||
/crypto-js@4.2.0:
|
||||
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
|
||||
dev: false
|
||||
|
||||
/css-loader@6.10.0(webpack@5.90.3):
|
||||
resolution: {integrity: sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==}
|
||||
engines: {node: '>= 12.13.0'}
|
||||
|
@ -5028,10 +4998,6 @@ packages:
|
|||
domelementtype: 2.3.0
|
||||
dev: true
|
||||
|
||||
/dompurify@3.1.3:
|
||||
resolution: {integrity: sha512-5sOWYSNPaxz6o2MUPvtyxTTqR4D3L77pr5rUQoWgD5ROQtVIZQgJkXbo1DLlK3vj11YGw5+LnF4SYti4gZmwng==}
|
||||
dev: false
|
||||
|
||||
/domutils@3.1.0:
|
||||
resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
|
||||
dependencies:
|
||||
|
|
|
@ -6,16 +6,16 @@
|
|||
</div>
|
||||
<div class="content-zone">
|
||||
<h1>
|
||||
@if (isSignupSignal()) {
|
||||
@if (this.isSignupSignal()) {
|
||||
Anmelden
|
||||
} @else if (isRegisterSignal()) {
|
||||
} @else if (this.isRegisterSignal()) {
|
||||
Registrieren
|
||||
} @else {
|
||||
Erste Schritte
|
||||
}
|
||||
</h1>
|
||||
|
||||
@if (isDisplayButtons()) {
|
||||
@if (this.isDisplayButtons()) {
|
||||
<div class="action">
|
||||
<button
|
||||
pButton
|
||||
|
@ -30,10 +30,10 @@
|
|||
</div>
|
||||
}
|
||||
|
||||
@if (isSignupSignal() || isRegisterSignal()) {
|
||||
<div class="register-wrapper">
|
||||
@if (form) {
|
||||
<form [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||
<div
|
||||
class="register-wrapper"
|
||||
*ngIf="isSignupSignal() || isRegisterSignal()">
|
||||
<form [formGroup]="form" *ngIf="form" (ngSubmit)="onSubmit()">
|
||||
<div class="e-mail">
|
||||
<div class="label">
|
||||
<label for="email">E-Mail</label>
|
||||
|
@ -55,13 +55,13 @@
|
|||
aria-describedby="password"
|
||||
[toggleMask]="true"></p-password>
|
||||
</div>
|
||||
@if (isRegisterSignal()) {
|
||||
@if (this.isRegisterSignal()) {
|
||||
<div class="terms">
|
||||
<p-checkbox
|
||||
formControlName="terms"
|
||||
label="Ich habe die AGB gelesen und stimme zu."
|
||||
name="terms"
|
||||
[binary]="true"></p-checkbox>
|
||||
[binary]="true" />
|
||||
</div>
|
||||
}
|
||||
<div class="signup">
|
||||
|
@ -69,17 +69,12 @@
|
|||
pButton
|
||||
type="submit"
|
||||
[label]="
|
||||
isSignupSignal()
|
||||
? 'Anmelden'
|
||||
: '✨ Jetzt KOSTENFREI loslegen ✨'
|
||||
isSignupSignal() ? 'Anmelden' : '✨ Jetzt KOSTENFREI loslegen ✨'
|
||||
"></button>
|
||||
</div>
|
||||
<div class="change-mask">
|
||||
<a
|
||||
(click)="switchMask()"
|
||||
(keyup.enter)="switchMask()"
|
||||
tabindex="0">
|
||||
@if (isSignupSignal()) {
|
||||
<a (click)="switchMask()" (keyup.enter)="switchMask()" tabindex="0">
|
||||
@if (this.isSignupSignal()) {
|
||||
Kein Account? Erstellen Sie jetzt KOSTENFREI einen!
|
||||
} @else {
|
||||
Schon einen Account? Hier einloggen
|
||||
|
@ -87,8 +82,6 @@
|
|||
</a>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,77 +1,38 @@
|
|||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { LoginCredentials, Tokens } from '../types';
|
||||
|
||||
import { LocalStorageService } from './local-storage.service';
|
||||
import { SessionStorageService } from './session-storage.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class AuthService {
|
||||
private readonly path: string = '/api/auth';
|
||||
private isAuthenticated: boolean = false;
|
||||
private access_token: string | null = null;
|
||||
private refresh_token: string | null = null;
|
||||
private isAuthenticated$: BehaviorSubject<boolean> =
|
||||
new BehaviorSubject<boolean>(false);
|
||||
|
||||
public constructor(
|
||||
private readonly httpClient: HttpClient,
|
||||
private readonly localStorageService: LocalStorageService,
|
||||
private readonly sessionStorageService: SessionStorageService
|
||||
private readonly router: Router
|
||||
) {}
|
||||
|
||||
public signin(credentials: LoginCredentials): void {
|
||||
this.httpClient
|
||||
.post<Tokens>(environment.api.base + `${this.path}/signin`, credentials)
|
||||
.post<Tokens>(environment.api.base + '/api/auth/signin', credentials)
|
||||
.subscribe((response: Tokens) => {
|
||||
this.handleSuccess(response);
|
||||
this.access_token = response.access_token;
|
||||
this.refresh_token = response.refresh_token;
|
||||
});
|
||||
}
|
||||
|
||||
public signup(credentials: LoginCredentials): void {
|
||||
this.httpClient
|
||||
.post<Tokens>(environment.api.base + `${this.path}/signup`, credentials)
|
||||
.post<Tokens>(environment.api.base + '/api/auth/signup', credentials)
|
||||
.subscribe((response: Tokens) => {
|
||||
// The checked accept terms should be saved with a timestamp in the db
|
||||
this.handleSuccess(response);
|
||||
this.access_token = response.access_token;
|
||||
this.refresh_token = response.refresh_token;
|
||||
});
|
||||
}
|
||||
|
||||
public signout(): void {
|
||||
this.access_token = null;
|
||||
this.refresh_token = null;
|
||||
this.localStorageService.removeItem('access_token');
|
||||
this.sessionStorageService.removeItem('refresh_token');
|
||||
this.isAuthenticated$.next(false);
|
||||
}
|
||||
|
||||
public refreshToken(): void {
|
||||
const headers = new HttpHeaders().set(
|
||||
'Authorization',
|
||||
'Bearer ' + this.refresh_token
|
||||
);
|
||||
|
||||
this.httpClient
|
||||
.post<Tokens>(
|
||||
environment.api.base + `${this.path}/refresh`,
|
||||
{},
|
||||
{ headers: headers }
|
||||
)
|
||||
.subscribe((response: Tokens) => {
|
||||
this.handleSuccess(response);
|
||||
});
|
||||
}
|
||||
|
||||
private handleSuccess(tokens: Tokens): void {
|
||||
this.access_token = tokens.access_token;
|
||||
this.refresh_token = tokens.refresh_token;
|
||||
this.localStorageService.setItem('access_token', tokens.access_token);
|
||||
this.sessionStorageService.setItem('refresh_token', tokens.refresh_token);
|
||||
this.isAuthenticated$.next(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
import { EncryptionService } from './encryption.service';
|
||||
import { SanitizationService } from './sanitization.service';
|
||||
|
||||
export abstract class BaseStorageService {
|
||||
protected abstract getStorage(): Storage;
|
||||
|
||||
public setItem<T>(key: string, value: T): void {
|
||||
const sanitizedValue = SanitizationService.sanitize(JSON.stringify(value));
|
||||
const encryptedValue = EncryptionService.encrypt(sanitizedValue);
|
||||
|
||||
this.getStorage().setItem(key, encryptedValue);
|
||||
}
|
||||
|
||||
public getItem<T>(key: string): T | null {
|
||||
const encryptedValue = this.getStorage().getItem(key);
|
||||
|
||||
if (encryptedValue) {
|
||||
const decryptedValue = EncryptionService.decrypt(encryptedValue);
|
||||
const sanitizedValue = SanitizationService.sanitize(decryptedValue);
|
||||
|
||||
return JSON.parse(sanitizedValue) as T;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public removeItem(key: string): void {
|
||||
this.getStorage().removeItem(key);
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this.getStorage().clear();
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import * as CryptoJS from 'crypto-js';
|
||||
|
||||
import { environment } from '../../../environments/environment';
|
||||
|
||||
export class EncryptionService {
|
||||
private static readonly key: string = environment.security.encryptionKey;
|
||||
|
||||
public static encrypt(data: string): string {
|
||||
return CryptoJS.AES.encrypt(data, this.key).toString();
|
||||
}
|
||||
|
||||
public static decrypt(data: string): string {
|
||||
return CryptoJS.AES.decrypt(data, this.key).toString(CryptoJS.enc.Utf8);
|
||||
}
|
||||
}
|
|
@ -1,3 +1 @@
|
|||
export * from './auth.service';
|
||||
export * from './local-storage.service';
|
||||
export * from './session-storage.service';
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { BaseStorageService } from './base-storage.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class LocalStorageService extends BaseStorageService {
|
||||
protected getStorage(): Storage {
|
||||
return localStorage;
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
import DOMPurify from 'dompurify';
|
||||
|
||||
export class SanitizationService {
|
||||
public static sanitize(data: string): string {
|
||||
return DOMPurify.sanitize(data);
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { BaseStorageService } from './base-storage.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class SessionStorageService extends BaseStorageService {
|
||||
protected getStorage(): Storage {
|
||||
return sessionStorage;
|
||||
}
|
||||
}
|
|
@ -3,9 +3,6 @@ export const environment = {
|
|||
api: {
|
||||
base: 'http://localhost:3000',
|
||||
},
|
||||
security: {
|
||||
encryptionKey: 'my-secret',
|
||||
},
|
||||
oauth: {
|
||||
clinetId: 'app_FLXnxSBnnaKkXoYCgk3J62iA',
|
||||
redirectUri: 'https://commonly-hot-airedale.ngrok-free.app/oauth',
|
||||
|
|
Loading…
Reference in New Issue