Commit ecc30837 authored by Thodoris Nestoridis's avatar Thodoris Nestoridis

trying tabe

parent 48f8ff50
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://155.207.131.19:8081/login",
"webRoot": "${workspaceFolder}"
}
]
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
...@@ -15,7 +15,7 @@ import { PrefixDetailsComponent } from './components/prefix-details/prefix-detai ...@@ -15,7 +15,7 @@ import { PrefixDetailsComponent } from './components/prefix-details/prefix-detai
import { AddPrefixComponent } from './components/add-prefix/add-prefix.component';*/ import { AddPrefixComponent } from './components/add-prefix/add-prefix.component';*/
const routes: Routes = [ const routes: Routes = [
{ path: '', redirectTo: 'login', pathMatch: 'full' }, { path: ' ', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent }, { path: 'login', component: LoginComponent },
{ path: 'signup', component: SignupComponent }, { path: 'signup', component: SignupComponent },
{ path: 'boilerplates', component: BoilerplateListComponent, canActivate: [AuthGuard] }, { path: 'boilerplates', component: BoilerplateListComponent, canActivate: [AuthGuard] },
......
<mat-sidenav-container> <div *ngIf="!LoggedIn()"> <router-outlet></router-outlet> </div>
<div *ngIf="LoggedIn()">
<mat-sidenav-container>
<mat-sidenav #sidenav role="navigation"> <mat-sidenav #sidenav role="navigation">
<!--this is a place for us to add side-nav code-->
<app-sidenav-list (sidenavClose)="sidenav.close()"></app-sidenav-list> <app-sidenav-list (sidenavClose)="sidenav.close()"></app-sidenav-list>
</mat-sidenav> </mat-sidenav>
<mat-sidenav-content> <mat-sidenav-content>
<!--in here all the content must reside. We will add a navigation header as well-->
<mat-sidenav-content> <mat-sidenav-content>
<app-header (sidenavToggle)="sidenav.toggle()"></app-header> <app-header (sidenavToggle)="sidenav.toggle()"></app-header>
<main> <main>
...@@ -12,4 +15,6 @@ ...@@ -12,4 +15,6 @@
</main> </main>
</mat-sidenav-content> </mat-sidenav-content>
</mat-sidenav-content> </mat-sidenav-content>
</mat-sidenav-container> </mat-sidenav-container>
</div>
<notifier-container></notifier-container>
\ No newline at end of file
import { Component } from '@angular/core'; import { Component, Output, EventEmitter } from '@angular/core';
import { AuthService } from './services/auth.service';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'] styleUrls: ['./app.component.scss']
}) })
export class AppComponent { export class AppComponent {
constructor(private authService: AuthService){}
title = 'ReqmanAngular11'; title = 'ReqmanAngular11';
LoggedIn() {
return this.authService.isLoggedIn();
}
}; };
\ No newline at end of file
...@@ -6,7 +6,7 @@ import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; ...@@ -6,7 +6,7 @@ import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthService, AuthInterceptor, AuthGuard } from './services/auth.service'; import { AuthService, AuthInterceptor, AuthGuard } from './services/auth.service';
...@@ -46,6 +46,7 @@ import { SidenavListComponent } from './navigation/sidenav-list/sidenav-list.com ...@@ -46,6 +46,7 @@ import { SidenavListComponent } from './navigation/sidenav-list/sidenav-list.com
imports: [ imports: [
BrowserModule, BrowserModule,
AppRoutingModule, AppRoutingModule,
ReactiveFormsModule,
FormsModule, FormsModule,
HttpClientModule, HttpClientModule,
NgbModule, NgbModule,
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
</div> </div>
</div> </div>
</div> </div>
<!--
<div class="col-md-6"> <div class="col-md-6">
<h4>Boilerplate List</h4> <h4>Boilerplate List</h4>
<ul class="list-group"> <ul class="list-group">
...@@ -57,6 +58,40 @@ ...@@ -57,6 +58,40 @@
</div> </div>
<div> <div>
<button class="btn btn-success" routerLink="/add-boilerplate">Add</button> <button class="btn btn-success" routerLink="/add-boilerplate">Add</button>
</div>-->
</div> </div>
</div>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!-- Position Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let element"> {{element.id}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef> Title </th>
<td mat-cell *matCellDef="let element"> {{element.title}} </td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="has_prefix">
<th mat-header-cell *matHeaderCellDef> Prefix </th>
<td mat-cell *matCellDef="let element"> {{element.has_prefix}} </td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="has_main">
<th mat-header-cell *matHeaderCellDef> Main </th>
<td mat-cell *matCellDef="let element"> {{element.has_main}} </td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="has_suffix">
<th mat-header-cell *matHeaderCellDef> Suffix </th>
<td mat-cell *matCellDef="let element"> {{element.has_suffix}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
...@@ -4,3 +4,6 @@ ...@@ -4,3 +4,6 @@
margin: auto; margin: auto;
} }
table {
width: 100%;
}
\ No newline at end of file
...@@ -2,17 +2,31 @@ import { Component, OnInit } from '@angular/core'; ...@@ -2,17 +2,31 @@ import { Component, OnInit } from '@angular/core';
import { Boilerplate } from 'src/app/models/boilerplate.model'; import { Boilerplate } from 'src/app/models/boilerplate.model';
import { BoilerplateService } from 'src/app/services/boilerplate.service'; import { BoilerplateService } from 'src/app/services/boilerplate.service';
export interface PeriodicElement {
id: number;
title: string;
has_prefix: boolean;
has_main: boolean;
has_suffix: boolean;
}
const ELEMENT_DATA: PeriodicElement[] = [{id: 5, title:"ss", has_prefix: false, has_main:true, has_suffix:true},
{id: 6, title:"s222s", has_prefix: false, has_main:true, has_suffix:true}];
@Component({ @Component({
selector: 'app-boilerplate-list', selector: 'app-boilerplate-list',
templateUrl: './boilerplate-list.component.html', templateUrl: './boilerplate-list.component.html',
styleUrls: ['./boilerplate-list.component.scss'] styleUrls: ['./boilerplate-list.component.scss']
}) })
export class BoilerplateListComponent implements OnInit { export class BoilerplateListComponent implements OnInit {
boilerplates?: Boilerplate[]; boilerplates?: Boilerplate[];
currentBoilerplate?: Boilerplate; currentBoilerplate?: Boilerplate;
currentIndex = -1; currentIndex = -1;
title = ''; title = '';
displayedColumns: string[] = ['id', 'title', 'has_prefix', 'has_main', 'has_suffix'];
dataSource = ELEMENT_DATA;
constructor(private boilerplateService: BoilerplateService) { } constructor(private boilerplateService: BoilerplateService) { }
...@@ -25,7 +39,9 @@ export class BoilerplateListComponent implements OnInit { ...@@ -25,7 +39,9 @@ export class BoilerplateListComponent implements OnInit {
.subscribe( .subscribe(
data => { data => {
this.boilerplates = data; this.boilerplates = data;
console.log(data); //this.boilerplates = this.dataSource;
data.forEach(val => this.dataSource.push(Object.assign(val)));
console.log(this.dataSource);
}, },
error => { error => {
console.log(error); console.log(error);
......
...@@ -12,39 +12,37 @@ ...@@ -12,39 +12,37 @@
<!-- Default form login --> <!-- Default form login -->
<form class="text-center border border-light p-5"> <div class="main-wrapper" fxLayout="row" fxLayoutAlign="center center">
<mat-card class="box">
<p class="h4 mb-4">Sign in</p> <mat-card-header>
<mat-card-title>Sign In</mat-card-title>
</mat-card-header>
<form class="example-form">
<!-- Email --> <!-- Email -->
<input #email type="email" id="defaultLoginFormEmail" class="form-control mb-4" placeholder="E-mail"> <mat-card-content>
<mat-form-field class="example-full-width">
<mat-label>Enter your email</mat-label>
<input matInput placeholder="pat@example.com" [formControl]="email" required>
<mat-error *ngIf="email.invalid">{{getErrorMessage()}}</mat-error>
</mat-form-field>
<!-- Password --> <!-- Password -->
<input #password type="password" id="defaultLoginFormPassword" class="form-control mb-4" placeholder="Password">
<div class="d-flex justify-content-around">
<div>
<!-- Remember me -->
<input
class="form-check-input"
type="checkbox"
value=""
id="flexCheckDefault"
/>
</div>
<div>
<!-- Forgot password -->
<a href="">Forgot password?</a>
</div>
</div>
<mat-form-field aclass="example-full-width">
<mat-label>Enter your password</mat-label>
<input matInput [type]="hide ? 'password' : 'text'" [formControl]="password" required>
<button mat-icon-button matSuffix (click)="hide = !hide" [attr.aria-label]="'Hide password'" [attr.aria-pressed]="hide">
<mat-icon>{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
</button>
</mat-form-field>
</mat-card-content>
<!-- Sign in button --> <!-- Sign in button -->
<button mdbBtn color="info" block="true" class="my-4" type="submit" (click)="login(email.value, password.value)">Log in</button> <button mat-stroked-button color="primary" class="btn-block" type="submit" (click)="login(email.value, password.value)">Log in</button>
<!-- Register --> <!-- Register -->
<p>Not a member? <p>Not a member?
<a href="">Register</a> <a href="#">Register</a>
</p> </p>
</form> </form>
</mat-card>
</div>
<!-- Default form login --> <!-- Default form login -->
\ No newline at end of file
.app-header {
justify-content: space-between;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 2;
box-shadow: 0 3px 5px -1px rgba(0, 0, 0, .2), 0 6px 10px 0 rgba(0, 0, 0, .14), 0 1px 18px 0 rgba(0, 0, 0, .12);
}
.main-wrapper {
height: 100%;
}
.positronx {
text-decoration: none;
color: #ffffff;
}
.box {
position: relative;
top: 0;
opacity: 1;
float: left;
padding: 60px 50px 40px 50px;
width: 100%;
background: #fff;
border-radius: 10px;
transform: scale(1);
-webkit-transform: scale(1);
-ms-transform: scale(1);
z-index: 5;
max-width: 330px;
}
.box.back {
transform: scale(.95);
-webkit-transform: scale(.95);
-ms-transform: scale(.95);
top: -20px;
opacity: .8;
z-index: -1;
}
.box:before {
content: "";
width: 100%;
height: 30px;
border-radius: 10px;
position: absolute;
top: -10px;
background: rgba(255, 255, 255, .6);
left: 0;
transform: scale(.95);
-webkit-transform: scale(.95);
-ms-transform: scale(.95);
z-index: -1;
}
.main-wrapper .example-form {
min-width: 100%;
max-width: 300px;
width: 100%;
padding: 20px ;
}
.main-wrapper .example-full-width,
.main-wrapper .btn-block {
width: 100%;
}
.main-wrapper mat-card-header {
text-align: center;
width: 100%;
display: block;
font-weight: 700;
}
.main-wrapper mat-card-header mat-card-title {
font-size: 30px;
margin: 0;
}
.main-wrapper .mat-card {
padding: center;
}
.main-wrapper .mat-stroked-button {
border: 1px solid currentColor;
line-height: 54px;
background: #FFF7FA;
}
.main-wrapper .mat-form-field-appearance-legacy .mat-form-field-infix {
padding: 0.8375em 0;
}
\ No newline at end of file
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AuthService } from './../../services/auth.service'; import { AuthService } from './../../services/auth.service';
import { NotifierService } from "angular-notifier";
import {FormControl, Validators} from '@angular/forms';
@Component({ @Component({
selector: 'app-login', selector: 'app-login',
...@@ -10,11 +12,23 @@ import { AuthService } from './../../services/auth.service'; ...@@ -10,11 +12,23 @@ import { AuthService } from './../../services/auth.service';
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
error: any; error: any;
private readonly notifier: NotifierService;
constructor( constructor(
private authService: AuthService, private authService: AuthService,
private router: Router, private router: Router,
) { } notifierService: NotifierService,
) {this.notifier = notifierService; }
hide = true;
email = new FormControl('', [Validators.required, Validators.email]);
password = new FormControl('');
getErrorMessage() {
if (this.email.hasError('required')) {
return 'You must enter a value';
}
return this.email.hasError('email') ? 'Not a valid email' : '';
}
ngOnInit() { ngOnInit() {
} }
...@@ -22,7 +36,7 @@ export class LoginComponent implements OnInit { ...@@ -22,7 +36,7 @@ export class LoginComponent implements OnInit {
login(email: string, password: string) { login(email: string, password: string) {
this.authService.login(email, password).subscribe( this.authService.login(email, password).subscribe(
success => this.router.navigate(['boilerplates']), success => this.router.navigate(['boilerplates']),
error => this.error = error error => this.notifier.notify("warning",(JSON.stringify("You have entered an invalid username or password")))
); );
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<a routerLink="/add-boilerplate">Add Boilepate</a> <a routerLink="/add-boilerplate">Add Boilepate</a>
</li> </li>
<li> <li>
<a routerLink="/account">Account Actions</a> <button mat-menu-item (click)="LogOut()">Log out</button>
</li> </li>
</ul> </ul>
</div> </div>
......
import { Component, OnInit, Output, EventEmitter} from '@angular/core'; import { Component, OnInit, Output, EventEmitter} from '@angular/core';
import { AuthService } from './../../services/auth.service';
@Component({ @Component({
selector: 'app-header', selector: 'app-header',
...@@ -9,11 +10,15 @@ export class HeaderComponent implements OnInit { ...@@ -9,11 +10,15 @@ export class HeaderComponent implements OnInit {
@Output() public sidenavToggle = new EventEmitter(); @Output() public sidenavToggle = new EventEmitter();
constructor() { } constructor(private authService: AuthService){}
ngOnInit(): void { ngOnInit(): void {
} }
public onToggleSidenav = () => { public onToggleSidenav = () => {
this.sidenavToggle.emit(); this.sidenavToggle.emit();
} }
LogOut() {
return this.authService.logout();
}
} }
...@@ -3,7 +3,7 @@ import { HttpClient, HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from ...@@ -3,7 +3,7 @@ import { HttpClient, HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from
import { CanActivate, Router } from '@angular/router'; import { CanActivate, Router } from '@angular/router';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { tap, shareReplay } from 'rxjs/operators'; import { tap, shareReplay, combineAll } from 'rxjs/operators';
import jwtDecode from 'jwt-decode'; import jwtDecode from 'jwt-decode';
import * as moment from 'moment'; import * as moment from 'moment';
...@@ -18,7 +18,7 @@ export class AuthService { ...@@ -18,7 +18,7 @@ export class AuthService {
private apiRoot = 'http://155.207.131.19:8000/auth/'; private apiRoot = 'http://155.207.131.19:8000/auth/';
constructor(private http: HttpClient) { } constructor(private http: HttpClient, private router:Router) { }
private setSession(authResult: any) { private setSession(authResult: any) {
const token = authResult.token; const token = authResult.token;
...@@ -29,7 +29,7 @@ export class AuthService { ...@@ -29,7 +29,7 @@ export class AuthService {
localStorage.setItem('expires_at', JSON.stringify(expiresAt.valueOf())); localStorage.setItem('expires_at', JSON.stringify(expiresAt.valueOf()));
} }
get token(): string { get_token(): string {
return JSON.parse(localStorage.getItem('currentUser') || '{}'); return JSON.parse(localStorage.getItem('currentUser') || '{}');
} }
...@@ -48,15 +48,22 @@ export class AuthService { ...@@ -48,15 +48,22 @@ export class AuthService {
} }
logout() { logout() {
const token = localStorage.getItem('token');
this.http.post(
this.apiRoot.concat('logout/'),
{ token: token }
);
localStorage.removeItem('token'); localStorage.removeItem('token');
localStorage.removeItem('expires_at'); localStorage.removeItem('expires_at');
this.router.navigate(['/login']);
} }
refreshToken() { refreshToken() {
const token = localStorage.getItem('token');
if (moment().isBetween(this.getExpiration().subtract(1, 'days'), this.getExpiration())) { if (moment().isBetween(this.getExpiration().subtract(1, 'days'), this.getExpiration())) {
return this.http.post( return this.http.post(
this.apiRoot.concat('refresh-token/'), this.apiRoot.concat('refresh-token/'),
{ token: this.token } { token: token }
).pipe( ).pipe(
tap(response => this.setSession(response)), tap(response => this.setSession(response)),
shareReplay(), shareReplay(),
...@@ -66,10 +73,13 @@ export class AuthService { ...@@ -66,10 +73,13 @@ export class AuthService {
} }
getExpiration() { getExpiration() {
try {
const expiration = JSON.parse(localStorage.getItem('expires_at') || '{}'); const expiration = JSON.parse(localStorage.getItem('expires_at') || '{}');
const expiresAt = JSON.parse(expiration); const expiresAt = JSON.parse(expiration);
return moment(expiresAt); return moment(expiresAt);
} catch(e){
return moment(0);}
} }
isLoggedIn() { isLoggedIn() {
......
...@@ -47,6 +47,7 @@ INSTALLED_APPS = [ ...@@ -47,6 +47,7 @@ INSTALLED_APPS = [
# 3rd party apps # 3rd party apps
"rest_framework", "rest_framework",
'corsheaders', 'corsheaders',
'rest_framework_jwt.blacklist',
# our apps # our apps
"reqman.apps.common.apps.CommonConfig", "reqman.apps.common.apps.CommonConfig",
"reqman.apps.account.apps.AccountConfig", "reqman.apps.account.apps.AccountConfig",
......
...@@ -17,6 +17,7 @@ from django.contrib import admin ...@@ -17,6 +17,7 @@ from django.contrib import admin
from django.conf import settings from django.conf import settings
from django.urls import path, include, re_path from django.urls import path, include, re_path
from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token
from rest_framework_jwt.blacklist.views import BlacklistView
urlpatterns = [ urlpatterns = [
...@@ -24,6 +25,7 @@ urlpatterns = [ ...@@ -24,6 +25,7 @@ urlpatterns = [
path('api-auth/', include('reqman.apps.reqtool.rest_api.urls')), path('api-auth/', include('reqman.apps.reqtool.rest_api.urls')),
path('auth/login/', obtain_jwt_token), path('auth/login/', obtain_jwt_token),
path('auth/refresh-token/', refresh_jwt_token), path('auth/refresh-token/', refresh_jwt_token),
path("auth/logout/", BlacklistView.as_view({"post": "create"}))
#re_path(r'api/(?P<version>[v1|v2]+)/', include('reqman.apps.reqtool.rest_api.urls')), #re_path(r'api/(?P<version>[v1|v2]+)/', include('reqman.apps.reqtool.rest_api.urls')),
#path('api/', include('reqman.apps.reqtool.rest_api.urls')) #path('api/', include('reqman.apps.reqtool.rest_api.urls'))
] ]
......
...@@ -67,6 +67,7 @@ rdflib==5.0.0 ...@@ -67,6 +67,7 @@ rdflib==5.0.0
sparqlwrapper==1.8.5 sparqlwrapper==1.8.5
django-jsonfield==1.4.1 django-jsonfield==1.4.1
djangorestframework-jwt==1.5.2 djangorestframework-jwt==1.5.2
drf-jwt==1.17.3
# The following packages are considered to be unsafe in a requirements file: # The following packages are considered to be unsafe in a requirements file:
# setuptools==41.2.0 # via ipdb, ipython # setuptools==41.2.0 # via ipdb, ipython
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment