Merge remote-tracking branch 'origin/main' into bot
This commit is contained in:
commit
26a6561682
@ -59,7 +59,10 @@ def login(data):
|
|||||||
if not check_password(query_user.password, password.encode("utf-8")): # Password incorrect
|
if not check_password(query_user.password, password.encode("utf-8")): # Password incorrect
|
||||||
abort(500, message="Unable to login")
|
abort(500, message="Unable to login")
|
||||||
|
|
||||||
token = jwt.encode({'email': query_user.email, 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=45)}, os.getenv('SECRET_KEY'), "HS256")
|
if query_user.email == os.getenv("BOT_EMAIL"):
|
||||||
|
token = jwt.encode({'email': query_user.email, 'exp': datetime.datetime.utcnow() + datetime.timedelta(days=365)}, os.getenv('SECRET_KEY'), "HS256")
|
||||||
|
else:
|
||||||
|
token = jwt.encode({'email': query_user.email, 'exp': datetime.datetime.utcnow() + datetime.timedelta(days=1)}, os.getenv('SECRET_KEY'), "HS256")
|
||||||
|
|
||||||
return make_response({"token": token}, 200, "Successfully logged in")
|
return make_response({"token": token}, 200, "Successfully logged in")
|
||||||
|
|
||||||
|
@ -41,12 +41,17 @@ def get_email_from_token_data():
|
|||||||
|
|
||||||
if token is not None:
|
if token is not None:
|
||||||
if ':' in token: # Maybe bot token, check if token valid and return username after ":" then
|
if ':' in token: # Maybe bot token, check if token valid and return username after ":" then
|
||||||
email = token.split(":")[1]
|
telegram_user_id = token.split(":")[1]
|
||||||
token = token.split(":")[0]
|
token = token.split(":")[0]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['email'] == os.getenv("BOT_EMAIL"):
|
if jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])['email'] == os.getenv("BOT_EMAIL"):
|
||||||
return email
|
res = db.session.query(User).filter_by(telegram_user_id=telegram_user_id).first()
|
||||||
|
|
||||||
|
if res is not None:
|
||||||
|
return res.as_dict()['email']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
except jwt.PyJWTError:
|
except jwt.PyJWTError:
|
||||||
|
@ -25,3 +25,4 @@ Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To u
|
|||||||
## Further help
|
## Further help
|
||||||
|
|
||||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
} from '@angular/common/http';
|
} from '@angular/common/http';
|
||||||
import { TokenStorageService } from '../Services/token.service';
|
import { TokenStorageService } from '../Services/token.service';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
const TOKEN_HEADER_KEY = 'Authorization'; // for Spring Boot back-end
|
const TOKEN_HEADER_KEY = 'Authorization';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthInterceptor implements HttpInterceptor {
|
export class AuthInterceptor implements HttpInterceptor {
|
||||||
constructor(private token: TokenStorageService) {}
|
constructor(private token: TokenStorageService) {}
|
||||||
|
16
frontend/src/app/Helpers/helper.service.spec.ts
Normal file
16
frontend/src/app/Helpers/helper.service.spec.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HelperService } from './helper.service';
|
||||||
|
|
||||||
|
describe('HelperService', () => {
|
||||||
|
let service: HelperService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(HelperService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
10
frontend/src/app/Helpers/helper.service.ts
Normal file
10
frontend/src/app/Helpers/helper.service.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Stock } from '../Models/stock.model';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class HelperService {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
}
|
6
frontend/src/app/Models/stock.model.ts
Normal file
6
frontend/src/app/Models/stock.model.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export class Stock {
|
||||||
|
count = 0;
|
||||||
|
price = 0;
|
||||||
|
symbol = '';
|
||||||
|
time = '';
|
||||||
|
}
|
@ -11,18 +11,19 @@ const httpOptions = {
|
|||||||
})
|
})
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
constructor(private http: HttpClient) {}
|
constructor(private http: HttpClient) {}
|
||||||
login(username: string, password: string): Observable<any> {
|
login(email: string, password: string): Observable<any> {
|
||||||
return this.http.post(AUTH_API + '/login', {
|
return this.http.post(AUTH_API + '/login', {
|
||||||
username,
|
email,
|
||||||
password,
|
password,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
register(username: string, password: string): Observable<any> {
|
register(email: string, username: string, password: string): Observable<any> {
|
||||||
return this.http.post(
|
return this.http.post(
|
||||||
AUTH_API + '/register',
|
AUTH_API + '/register',
|
||||||
{
|
{
|
||||||
username,
|
email,
|
||||||
password,
|
password,
|
||||||
|
username,
|
||||||
},
|
},
|
||||||
httpOptions
|
httpOptions
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable, OnInit } from '@angular/core';
|
||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||||
import { Observable } from 'rxjs';
|
import { delay, Observable } from 'rxjs';
|
||||||
import { TokenStorageService } from './token.service';
|
import { TokenStorageService } from './token.service';
|
||||||
const API_URL = 'https://aktienbot.flokaiser.com/api/';
|
const API_URL = 'https://aktienbot.flokaiser.com/api/';
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@ -12,26 +12,32 @@ export class DataService {
|
|||||||
private tokenStorage: TokenStorageService
|
private tokenStorage: TokenStorageService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
headers = new HttpHeaders({
|
public getStockData(): Observable<any> {
|
||||||
'Content-Type': 'application/json',
|
return this.http.get(API_URL + 'portfolio', {
|
||||||
Authorization: 'Bearer ' + this.tokenStorage.getToken(),
|
headers: new HttpHeaders({
|
||||||
});
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: 'Bearer ' + this.tokenStorage.getToken(),
|
||||||
async getStockData() {
|
}),
|
||||||
await this.http
|
responseType: 'text',
|
||||||
.get(API_URL + 'portfolio', {
|
});
|
||||||
headers: this.headers,
|
|
||||||
responseType: 'text',
|
|
||||||
})
|
|
||||||
.subscribe((data) => {
|
|
||||||
console.log(data);
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getKeywords(): Observable<any> {
|
public getTransactionData(): Observable<any> {
|
||||||
|
return this.http.get(API_URL + 'transactions', {
|
||||||
|
headers: new HttpHeaders({
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: 'Bearer ' + this.tokenStorage.getToken(),
|
||||||
|
}),
|
||||||
|
responseType: 'text',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getKeywords(): Observable<any> {
|
||||||
return this.http.get(API_URL + 'keywords', {
|
return this.http.get(API_URL + 'keywords', {
|
||||||
headers: this.headers,
|
headers: new HttpHeaders({
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: 'Bearer ' + this.tokenStorage.getToken(),
|
||||||
|
}),
|
||||||
responseType: 'text',
|
responseType: 'text',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,39 @@
|
|||||||
<div class="heading fix-right-side">
|
<div class="heading fix-right-side">
|
||||||
<div class="vertical-center">Transaktionen</div>
|
<div class="vertical-center">Transaktionen</div>
|
||||||
</div>
|
</div>
|
||||||
<mat-card class="placeholder"></mat-card>
|
<div class="stockTable">
|
||||||
|
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||||
|
<!--- Note that these columns can be defined in any order.
|
||||||
|
The actual rendered columns are set as a property on the row definition" -->
|
||||||
|
|
||||||
|
<!-- Position Column -->
|
||||||
|
<ng-container matColumnDef="position">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Count</th>
|
||||||
|
<td mat-cell *matCellDef="let element">{{ element.position }}</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Name Column -->
|
||||||
|
<ng-container matColumnDef="name">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Pirce</th>
|
||||||
|
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Weight Column -->
|
||||||
|
<ng-container matColumnDef="weight">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Symbol</th>
|
||||||
|
<td mat-cell *matCellDef="let element">{{ element.weight }}</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Symbol Column -->
|
||||||
|
<ng-container matColumnDef="symbol">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Time</th>
|
||||||
|
<td mat-cell *matCellDef="let element">{{ element.symbol }}</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</mat-grid-tile>
|
</mat-grid-tile>
|
||||||
</mat-grid-list>
|
</mat-grid-list>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { throwToolbarMixedModesError } from '@angular/material/toolbar';
|
import { throwToolbarMixedModesError } from '@angular/material/toolbar';
|
||||||
import { DataService } from 'src/app/Services/data.service';
|
import { DataService } from 'src/app/Services/data.service';
|
||||||
|
import { TokenStorageService } from 'src/app/Services/token.service';
|
||||||
|
|
||||||
export interface PeriodicElement {
|
export interface PeriodicElement {
|
||||||
name: string;
|
name: string;
|
||||||
@ -49,11 +50,15 @@ const ELEMENT_DATA: PeriodicElement[] = [
|
|||||||
})
|
})
|
||||||
export class DashboardComponent implements OnInit {
|
export class DashboardComponent implements OnInit {
|
||||||
constructor(private dataService: DataService) {}
|
constructor(private dataService: DataService) {}
|
||||||
|
ngOnInit() {
|
||||||
//TODO avoid using ngOnInit() like this
|
this.dataService.getStockData().subscribe((response: any) => {
|
||||||
//TODO fix server problems
|
console.log(response);
|
||||||
async ngOnInit() {
|
//TODO map data on array for display
|
||||||
const data = await this.dataService.getStockData();
|
});
|
||||||
|
this.dataService.getTransactionData().subscribe((response: any) => {
|
||||||
|
console.log(response);
|
||||||
|
//TODO map data on array for display
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
|
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
|
||||||
|
@ -14,21 +14,21 @@
|
|||||||
class="backgorund"
|
class="backgorund"
|
||||||
>
|
>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="username">Username</label>
|
<label for="email">Email</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="email"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="username"
|
name="email"
|
||||||
[(ngModel)]="form.username"
|
[(ngModel)]="form.email"
|
||||||
required
|
required
|
||||||
#username="ngModel"
|
email
|
||||||
|
#email="ngModel"
|
||||||
/>
|
/>
|
||||||
<div
|
<div class="alert-danger" *ngIf="email.errors && f.submitted">
|
||||||
class="alert alert-danger"
|
<div *ngIf="email.errors?.['required']">Email is required</div>
|
||||||
role="alert"
|
<div *ngIf="email.errors?.['email']">
|
||||||
*ngIf="username.errors && f.submitted"
|
Email must be a valid email address
|
||||||
>
|
</div>
|
||||||
Username is required!
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -10,7 +10,7 @@ import { Router } from '@angular/router';
|
|||||||
})
|
})
|
||||||
export class LoginComponent implements OnInit {
|
export class LoginComponent implements OnInit {
|
||||||
form: any = {
|
form: any = {
|
||||||
username: null,
|
email: null,
|
||||||
password: null,
|
password: null,
|
||||||
};
|
};
|
||||||
isLoggedIn = false;
|
isLoggedIn = false;
|
||||||
@ -29,7 +29,7 @@ export class LoginComponent implements OnInit {
|
|||||||
private router: Router
|
private router: Router
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
//ngOnInit() checks if a
|
//ngOnInit() checks if a user is logged in
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.tokenStorage.signOut();
|
this.tokenStorage.signOut();
|
||||||
if (this.tokenStorage.getToken()) {
|
if (this.tokenStorage.getToken()) {
|
||||||
@ -39,15 +39,15 @@ export class LoginComponent implements OnInit {
|
|||||||
|
|
||||||
//onSubmit() saves valuable information in session storage
|
//onSubmit() saves valuable information in session storage
|
||||||
onSubmit(): void {
|
onSubmit(): void {
|
||||||
const { username, password } = this.form;
|
const { email, password } = this.form;
|
||||||
this.authService.login(username, password).subscribe(
|
this.authService.login(email, password).subscribe(
|
||||||
(data) => {
|
(data) => {
|
||||||
this.tokenStorage.saveToken(data.data.token);
|
this.tokenStorage.saveToken(data.data.token);
|
||||||
this.tokenStorage.saveUser(data.data);
|
this.tokenStorage.saveUser(data.data);
|
||||||
|
|
||||||
this.isLoginFailed = false;
|
this.isLoginFailed = false;
|
||||||
this.isLoggedIn = true;
|
this.isLoggedIn = true;
|
||||||
this.accountName = username;
|
this.accountName = email;
|
||||||
this.router.navigate(['']);
|
this.router.navigate(['']);
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
|
@ -35,6 +35,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email">Email</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
class="form-control"
|
||||||
|
name="email"
|
||||||
|
[(ngModel)]="form.email"
|
||||||
|
required
|
||||||
|
email
|
||||||
|
#email="ngModel"
|
||||||
|
/>
|
||||||
|
<div class="alert-danger" *ngIf="email.errors && f.submitted">
|
||||||
|
<div *ngIf="email.errors?.['required']">Email is required</div>
|
||||||
|
<div *ngIf="email.errors?.['email']">
|
||||||
|
Email must be a valid email address
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
<input
|
<input
|
||||||
|
@ -9,8 +9,9 @@ import { AuthService } from '../../Services/auth.service';
|
|||||||
})
|
})
|
||||||
export class RegisterComponent implements OnInit {
|
export class RegisterComponent implements OnInit {
|
||||||
form: any = {
|
form: any = {
|
||||||
username: null,
|
email: null,
|
||||||
password: null,
|
password: null,
|
||||||
|
username: null,
|
||||||
};
|
};
|
||||||
isSuccessful = false;
|
isSuccessful = false;
|
||||||
isSignUpFailed = false;
|
isSignUpFailed = false;
|
||||||
@ -23,8 +24,8 @@ export class RegisterComponent implements OnInit {
|
|||||||
constructor(private authService: AuthService, private router: Router) {}
|
constructor(private authService: AuthService, private router: Router) {}
|
||||||
ngOnInit(): void {}
|
ngOnInit(): void {}
|
||||||
onSubmit(): void {
|
onSubmit(): void {
|
||||||
const { username, password } = this.form;
|
const { email, username, password } = this.form;
|
||||||
this.authService.register(username, password).subscribe(
|
this.authService.register(email, username, password).subscribe(
|
||||||
(data) => {
|
(data) => {
|
||||||
this.isSuccessful = true;
|
this.isSuccessful = true;
|
||||||
this.isSignUpFailed = false;
|
this.isSignUpFailed = false;
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
<title>Aktienbot</title>
|
<title>Aktienbot</title>
|
||||||
<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="frontend/Aktienbot/src/favicon.ico" />
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
|
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
|
||||||
|
Loading…
Reference in New Issue
Block a user