aboutsummaryrefslogtreecommitdiff
path: root/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src')
-rw-r--r--frontend/src/app/_data/Dataset.ts5
-rw-r--r--frontend/src/app/_data/Model.ts3
-rw-r--r--frontend/src/app/_data/Predictor.ts5
-rw-r--r--frontend/src/app/_elements/navbar/navbar.component.html2
-rw-r--r--frontend/src/app/_elements/navbar/navbar.component.ts6
-rw-r--r--frontend/src/app/_modals/login-modal/login-modal.component.ts3
-rw-r--r--frontend/src/app/_modals/register-modal/register-modal.component.html142
-rw-r--r--frontend/src/app/_modals/register-modal/register-modal.component.ts6
-rw-r--r--frontend/src/app/_services/auth.service.ts46
9 files changed, 144 insertions, 74 deletions
diff --git a/frontend/src/app/_data/Dataset.ts b/frontend/src/app/_data/Dataset.ts
index b4e46315..aaee50eb 100644
--- a/frontend/src/app/_data/Dataset.ts
+++ b/frontend/src/app/_data/Dataset.ts
@@ -5,6 +5,9 @@ export default class Dataset {
public header: string[] = [],
public fileId?: number,
public extension: string = '.csv',
- public dateCreated: Date = new Date()
+ public isPublic: boolean = false,
+ public accessibleByLink: boolean = false,
+ public dateCreated: Date = new Date(),
+ public lastUpdated: Date = new Date()
) { }
} \ No newline at end of file
diff --git a/frontend/src/app/_data/Model.ts b/frontend/src/app/_data/Model.ts
index 162d5d78..1a120ca7 100644
--- a/frontend/src/app/_data/Model.ts
+++ b/frontend/src/app/_data/Model.ts
@@ -3,9 +3,10 @@ export default class Model {
public name: string = 'Novi model',
public description: string = '',
public dateCreated: Date = new Date(),
+ public lastUpdated: Date = new Date(),
public datasetId?: number,
- //Test set settings
+ // Test set settings
public inputColumns: number[] = [0],
public columnToPredict: number = 1,
public randomOrder: boolean = true,
diff --git a/frontend/src/app/_data/Predictor.ts b/frontend/src/app/_data/Predictor.ts
index 379526ec..77d9498b 100644
--- a/frontend/src/app/_data/Predictor.ts
+++ b/frontend/src/app/_data/Predictor.ts
@@ -2,8 +2,9 @@ export default class Dataset {
constructor(
public name: string = 'Novi izvor podataka',
public description: string = '',
- public inputs: string[] = [],
- public output: string = '',
+ public columns: string[] = [],
+ public isPublic: boolean = false,
+ public accessibleByLink: boolean = false,
public dateCreated: Date = new Date()
) { }
} \ No newline at end of file
diff --git a/frontend/src/app/_elements/navbar/navbar.component.html b/frontend/src/app/_elements/navbar/navbar.component.html
index 426332bd..cea41e5a 100644
--- a/frontend/src/app/_elements/navbar/navbar.component.html
+++ b/frontend/src/app/_elements/navbar/navbar.component.html
@@ -30,7 +30,7 @@
<li>
<hr class="dropdown-divider">
</li>
- <li><a class="dropdown-item" href="#">Odjavi se</a></li>
+ <li><a class="dropdown-item" (click)="logOut()">Odjavi se</a></li>
</ul>
</div>
<div *ngIf="!shared.loggedIn" class="dropdown text-end">
diff --git a/frontend/src/app/_elements/navbar/navbar.component.ts b/frontend/src/app/_elements/navbar/navbar.component.ts
index 154a0d7d..c16e3e9d 100644
--- a/frontend/src/app/_elements/navbar/navbar.component.ts
+++ b/frontend/src/app/_elements/navbar/navbar.component.ts
@@ -18,11 +18,13 @@ export class NavbarComponent implements OnInit {
this.location.onUrlChange(() => {
this.currentUrl = this.location.path();
})
-
- this.shared.loggedIn = auth.isAuthenticated();
}
ngOnInit(): void {
+ this.auth.updateUser();
}
+ logOut() {
+ this.auth.logOut();
+ }
}
diff --git a/frontend/src/app/_modals/login-modal/login-modal.component.ts b/frontend/src/app/_modals/login-modal/login-modal.component.ts
index 22bd9a28..87686f10 100644
--- a/frontend/src/app/_modals/login-modal/login-modal.component.ts
+++ b/frontend/src/app/_modals/login-modal/login-modal.component.ts
@@ -27,9 +27,8 @@ export class LoginModalComponent implements OnInit {
doLogin() {
this.authService.login(this.username, this.password).subscribe((response) => { //ako nisu ok podaci, ne ide hide nego mora opet da ukucava!!!!podesi
console.log(response);
- this.cookie.set('token', response);
+ this.authService.authenticate(response);
(<HTMLSelectElement>document.getElementById('closeButton')).click();
- this.router.navigate(['add-model']);
}, error => {
console.warn(error); //NETACNI PODACI
});
diff --git a/frontend/src/app/_modals/register-modal/register-modal.component.html b/frontend/src/app/_modals/register-modal/register-modal.component.html
index 7ed2bbac..7098c040 100644
--- a/frontend/src/app/_modals/register-modal/register-modal.component.html
+++ b/frontend/src/app/_modals/register-modal/register-modal.component.html
@@ -1,70 +1,88 @@
<!-- Modal -->
-<div class="modal fade" id="modalForRegister" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
-<div class="modal-dialog modal-dialog-centered modal-dialog modal-lg">
- <div class="modal-content">
- <div class="modal-header" style="background-color: #003459;">
- <button type="button" class="btn-close" data-bs-dismiss="modal" style="background-color: white;" aria-label="Close" (click)="resetData()"></button>
- </div>
- <div class="modal-body" style="color:#003459">
- <h1 class="text-center mt-2 mb-4">Registracija</h1>
-
- <form class="mx-5">
- <!--Ime-->
- <div class="row">
- <div class="col-6 px-3 py-3">
- <label class="form-label" for="firstName">Ime</label>
- <input type="text" id="firstName" class="form-control" [(ngModel)]="firstName" name="firstName" placeholder="Unesite ime...">
- <small *ngIf="wrongFirstNameBool" class="form-text text-danger">Unesite ispravno ime.</small>
- </div>
- <!--Prezime-->
- <div class="col-6 px-3 py-3">
- <label class="form-label" for="lastName">Prezime</label>
- <input type="text" id="lastName" class="form-control" [(ngModel)]="lastName" name="lastName" placeholder="Unesite prezime..."/>
- <small *ngIf="wrongLastNameBool" class="form-text text-danger">Unesite ispravno prezime.</small>
- </div>
+<div class="modal fade" id="modalForRegister" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"
+ aria-labelledby="staticBackdropLabel" aria-hidden="true">
+ <div class="modal-dialog modal-dialog-centered modal-dialog modal-lg">
+ <div class="modal-content">
+ <div class="modal-header" style="background-color: #003459;">
+ <button type="button" class="btn-close" data-bs-dismiss="modal" style="background-color: white;"
+ aria-label="Close" (click)="resetData()"></button>
</div>
- <div class="row">
- <!--Korisnicko ime-->
- <div class="col-12 px-3 py-3">
- <label class="form-label" for="username">Korisničko ime</label>
- <input type="text" id="username" class="form-control" [(ngModel)]="username" name="username" placeholder="Unesite korisničko ime..."/>
- <small *ngIf="wrongUsernameBool" class="form-text text-danger">Unesite ispravno korisničko ime.</small>
+ <div class="modal-body" style="color:#003459">
+ <h1 class="text-center mt-2 mb-4">Registracija</h1>
+
+ <form class="mx-5">
+ <!--Ime-->
+ <div class="row">
+ <div class="col-6 px-3 py-3">
+ <label class="form-label" for="firstName">Ime</label>
+ <input type="text" id="firstName" class="form-control" [(ngModel)]="firstName"
+ name="firstName" placeholder="Unesite ime...">
+ <small *ngIf="wrongFirstNameBool" class="form-text text-danger">Unesite ispravno
+ ime.</small>
+ </div>
+ <!--Prezime-->
+ <div class="col-6 px-3 py-3">
+ <label class="form-label" for="lastName">Prezime</label>
+ <input type="text" id="lastName" class="form-control" [(ngModel)]="lastName" name="lastName"
+ placeholder="Unesite prezime..." />
+ <small *ngIf="wrongLastNameBool" class="form-text text-danger">Unesite ispravno
+ prezime.</small>
+ </div>
+ </div>
+ <div class="row">
+ <!--Korisnicko ime-->
+ <div class="col-12 px-3 py-3">
+ <label class="form-label" for="username-register">Korisničko ime</label>
+ <input type="text" id="username-register" class="form-control" [(ngModel)]="username"
+ name="username-register" placeholder="Unesite korisničko ime..." />
+ <small *ngIf="wrongUsernameBool" class="form-text text-danger">Unesite ispravno korisničko
+ ime.</small>
+ </div>
+ </div>
+ <div class="row">
+ <!--Email-->
+ <div class="col-12 px-3 py-3">
+ <label class="form-label" for="email">E-mail adresa</label>
+ <input type="email" id="email" class="form-control" [(ngModel)]="email" name="email"
+ placeholder="Unesite email adresu..." />
+ <small *ngIf="wrongEmailBool" class="form-text text-danger">Unesite ispravno e-mail
+ adresu.</small>
+ </div>
+ </div>
+ <div class="row">
+ <!-- Lozinka 1. -->
+ <div class="col-6 px-3 py-3">
+ <label class="form-label" for="pass1">Lozinka</label>
+ <input type="password" id="pass1" class="form-control" [(ngModel)]="pass1" name="pass1"
+ placeholder="Unesite lozinku..." />
+ <small *ngIf="wrongPass1Bool" class="form-text text-danger">Lozinka se mora sastojati od
+ najmanje 6 karaktera.</small>
+ </div>
+ <!-- Lozinka 2. -->
+ <div class="col-6 px-3 py-3">
+ <label class="form-label" for="pass2">Potvrdite lozinku</label>
+ <input type="password" id="pass2" class="form-control" [(ngModel)]="pass2" name="pass2"
+ placeholder="Ponovite lozinku..." />
+ <small *ngIf="wrongPass2Bool" class="form-text text-danger">Lozinke se ne
+ podudaraju.</small>
+ </div>
+ </div>
+ </form>
+ <div class="col-md-12 d-flex justify-content-center mt-5">
+ <button type="button" class="btn btn-lg"
+ style="color:white; background-color: #003459; margin-right: 10px;"
+ (click)="doRegister()">Registrujte se</button>
+ <button type="button" class="btn btn-lg btn-outline-secondary" style="margin-left: 15px;"
+ data-bs-dismiss="modal" (click)="resetData()">Odustanite</button>
</div>
+ <br>
</div>
- <div class="row">
- <!--Email-->
- <div class="col-12 px-3 py-3">
- <label class="form-label" for="email">E-mail adresa</label>
- <input type="email" id="email" class="form-control" [(ngModel)]="email" name="email" placeholder="Unesite email adresu..."/>
- <small *ngIf="wrongEmailBool" class="form-text text-danger">Unesite ispravno e-mail adresu.</small>
- </div>
+ <div class="modal-footer justify-content-center">
+ <p class="small fw-bold">Već imate kreiran nalog?
+ <a id="linkToLoginModal" data-bs-toggle="modal" data-bs-target="#modalForLogin"
+ class="link-danger">Prijavite se</a>
+ </p>
</div>
- <div class="row">
- <!-- Lozinka 1. -->
- <div class="col-6 px-3 py-3">
- <label class="form-label" for="pass1">Lozinka</label>
- <input type="password" id="pass1" class="form-control" [(ngModel)]="pass1" name="pass1" placeholder="Unesite lozinku..."/>
- <small *ngIf="wrongPass1Bool" class="form-text text-danger">Lozinka se mora sastojati od najmanje 6 karaktera.</small>
- </div>
- <!-- Lozinka 2. -->
- <div class="col-6 px-3 py-3">
- <label class="form-label" for="pass2">Potvrdite lozinku</label>
- <input type="password" id="pass2" class="form-control" [(ngModel)]="pass2" name="pass2" placeholder="Ponovite lozinku..."/>
- <small *ngIf="wrongPass2Bool" class="form-text text-danger">Lozinke se ne podudaraju.</small>
- </div>
- </div>
- </form>
- <div class="col-md-12 d-flex justify-content-center mt-5">
- <button type="button" class="btn btn-lg" style="color:white; background-color: #003459; margin-right: 10px;" (click)="doRegister()">Registrujte se</button>
- <button type="button" class="btn btn-lg btn-outline-secondary" style="margin-left: 15px;" data-bs-dismiss="modal" (click)="resetData()">Odustanite</button>
</div>
- <br>
- </div>
- <div class="modal-footer justify-content-center">
- <p class="small fw-bold">Već imate kreiran nalog?
- <a id="linkToLoginModal" data-bs-toggle="modal" data-bs-target="#modalForLogin" class="link-danger">Prijavite se</a>
- </p>
- </div>
</div>
-</div>
</div> \ No newline at end of file
diff --git a/frontend/src/app/_modals/register-modal/register-modal.component.ts b/frontend/src/app/_modals/register-modal/register-modal.component.ts
index 688fc806..c02a4e1a 100644
--- a/frontend/src/app/_modals/register-modal/register-modal.component.ts
+++ b/frontend/src/app/_modals/register-modal/register-modal.component.ts
@@ -48,7 +48,7 @@ export class RegisterModalComponent implements OnInit {
return true;
return false;
}
- isCorrectUsername(element: string) : boolean {
+ isCorrectUsername(element: string): boolean {
if (this.pattUsername.test(element) && !(this.pattTwoSpaces.test(element)) && (element.length >= 1 && element.length <= 30))
return true;
return false;
@@ -85,7 +85,7 @@ export class RegisterModalComponent implements OnInit {
this.wrongUsernameBool = false;
return;
}
- (<HTMLSelectElement>document.getElementById('username')).focus();
+ (<HTMLSelectElement>document.getElementById('username-register')).focus();
this.wrongUsernameBool = true;
}
emailValidation() {
@@ -146,7 +146,7 @@ export class RegisterModalComponent implements OnInit {
}
else if (response === 'Username Already Exists') {
alert('Nalog sa unetim korisničkim imenom već postoji!');
- (<HTMLSelectElement>document.getElementById('username')).focus();
+ (<HTMLSelectElement>document.getElementById('username-register')).focus();
}
}
);
diff --git a/frontend/src/app/_services/auth.service.ts b/frontend/src/app/_services/auth.service.ts
index c96c2dae..e6611880 100644
--- a/frontend/src/app/_services/auth.service.ts
+++ b/frontend/src/app/_services/auth.service.ts
@@ -3,6 +3,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http';
import { JwtHelperService } from '@auth0/angular-jwt';
import { CookieService } from 'ngx-cookie-service';
import { API_SETTINGS } from 'src/config';
+import shared from '../Shared';
const jwtHelper = new JwtHelperService();
@@ -11,6 +12,8 @@ const jwtHelper = new JwtHelperService();
})
export class AuthService {
+ shared = shared;
+
constructor(private http: HttpClient, private cookie: CookieService) { }
login(username: string, password: string) {
@@ -28,4 +31,47 @@ export class AuthService {
}
return false;
}
+
+ lastToken?: string;
+ refresher: any;
+
+ enableAutoRefresh() {
+ this.lastToken = this.cookie.get('token');
+ let exp = jwtHelper.getTokenExpirationDate(this.lastToken);
+ if (!exp) {
+ exp = new Date();
+ }
+ console.log(exp, exp?.getTime());
+ this.refresher = setTimeout(() => {
+ console.log('refreshing token!');
+ this.http.post(`${API_SETTINGS.apiURL}/auth/renewJwt`, {}, { headers: this.authHeader(), responseType: 'text' }).subscribe((response) => {
+ this.authenticate(response);
+ });
+ }, exp.getTime() - new Date().getTime());
+ }
+
+ authenticate(token: string) {
+ const user = jwtHelper.decodeToken(token);
+ this.cookie.set('token', token, user.exp);
+ this.updateUser();
+ }
+
+ updateUser() {
+ if (this.cookie.check('token')) {
+ const token = this.cookie.get('token');
+ this.shared.loggedIn = this.isAuthenticated();
+ this.enableAutoRefresh();
+ }
+ }
+
+ logOut() {
+ this.cookie.delete('token');
+ if (this.refresher)
+ clearTimeout(this.refresher);
+ this.shared.loggedIn = false;
+ }
+
+ authHeader() {
+ return new HttpHeaders().set("Authorization", "Bearer " + this.cookie.get('token'));
+ }
}