diff --git a/backend/app.js b/backend/app.js index 310c7d1..467a93e 100644 --- a/backend/app.js +++ b/backend/app.js @@ -271,7 +271,7 @@ app.get('/api/countries', (req, res, next) => { app.get('/api/users', (req, res, next) => { console.log('Get: /api/users'); - usermodel.find({'address': req.query.address, 'session': req.query.session}). + usermodel.find({'address': req.query.address, 'session': req.query.session, 'expired': { $ne: true}}). then((documents) => { if (documents != null) { res.status(200).json({ @@ -309,8 +309,7 @@ app.get('/api/pending', (req, res, next) => { app.get('/api/getuser', (req, res, next) => { console.log('Get: /api/getuser/', req.query.session); - var today = new Date().getTime() / 1000; - usermodel.find({'session': req.query.session, 'expiration': { $gt: today }}). + usermodel.find({'session': req.query.session, 'expired': { $ne: true }}). then((documents) => { if(documents.length > 0){ //console.log(documents); @@ -478,6 +477,19 @@ app.delete('/api/item/:id', (req, res, next) => { }); }); +app.delete('/api/user/:id', (req, res, next) => { + console.log("Delete user", req.params.id); + usermodel.findByIdAndUpdate(req.params.id, {expired: true}, function(err, docs) { + if (err) { + console.log(err); + } else { + res.status(200).json({ + message: 'User session deleted' + }); + } + }); +}); + app.get('/api/price', (req, res, next) => { console.log('Get /api/price'); const price = pricemodel.findOne({currency: req.query.currency}).then((document) => { diff --git a/backend/models/user.js b/backend/models/user.js index 4ac0030..11a983b 100644 --- a/backend/models/user.js +++ b/backend/models/user.js @@ -5,7 +5,8 @@ const userSchema = mongoose.Schema({ session: {type: String, required:true}, blocktime: {type: Number, required:true}, pin: {type: String, required:true}, - validated: {type: Boolean, required:true} + validated: {type: Boolean, required:true}, + expired: {type: Boolean, required:true, default: false} }); module.exports = mongoose.model('User', userSchema); diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index f555a0b..1e62d63 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -12,7 +12,7 @@ const routes: Routes = [ //{ path: 'create', component: PostCreateComponent, canActivate: [AuthGuardService]}, { path: 'shop', component: ViewerComponent, canActivate: [AuthGuardService]}, { path: 'orders', component: ListOrdersComponent, canActivate: [AuthGuardService]}, - { path: 'biz', component: BusinessComponent}, + { path: 'biz', component: BusinessComponent, canActivate: [AuthGuardService]}, { path: 'login', component: LoginComponent, resolve: { response: NodeResolverService}} ]; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5d82831..88af6cd 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -36,6 +36,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BusinessComponent } from './business/business.component'; import { SearchOptionsPipe } from './searchoptions.pipe'; import { TermsComponent } from './terms/terms.component'; +import { LogoutComponent } from './logout/logout.component'; @NgModule({ declarations: [ @@ -55,7 +56,8 @@ import { TermsComponent } from './terms/terms.component'; ListOrdersComponent, BusinessComponent, SearchOptionsPipe, - TermsComponent + TermsComponent, + LogoutComponent ], imports: [ BrowserModule, diff --git a/src/app/auth-guard.service.ts b/src/app/auth-guard.service.ts index 1a05680..c1bf887 100644 --- a/src/app/auth-guard.service.ts +++ b/src/app/auth-guard.service.ts @@ -25,6 +25,8 @@ export class AuthGuardService implements CanActivate { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { const token = localStorage.getItem('s4z_token'); + + var path = route.url[0].path; if(token != null){ this.userService.uZaddrUpdate. @@ -36,11 +38,20 @@ export class AuthGuardService implements CanActivate { console.log("No record for that token"); } }); - if (this.addr != null && this.paid) { - return true; + if (path === 'biz') { + if (this.addr.length > 0) { + return true; + } else { + this.router.navigate(['/login']); + return false; + } } else { - this.router.navigate(['/login']); - return false; + if (this.addr != null && this.paid) { + return true; + } else { + this.router.navigate(['/login']); + return false; + } } } else { console.log("Not logged in"); diff --git a/src/app/business/business.component.ts b/src/app/business/business.component.ts index daffb0f..f8fd1f1 100644 --- a/src/app/business/business.component.ts +++ b/src/app/business/business.component.ts @@ -24,6 +24,7 @@ import { TermsComponent } from '../terms/terms.component'; export class BusinessComponent implements OnInit { @ViewChild('stepper', { static: false}) stepper: MatStepper|undefined; + intervalHolder: any; nodeAddress: string = ''; tickets = [ { @@ -114,6 +115,9 @@ export class BusinessComponent implements OnInit { } ngOnInit(): void { + this.intervalHolder = setInterval(() => { + this.loginCheck(); + }, 1000 * 60); } ngAfterViewInit(): void { @@ -148,8 +152,8 @@ export class BusinessComponent implements OnInit { taxValue: 0, vat: false, vatValue: 0, - first: '', - last: '', + first: this.bizForm.get('first')!.value, + last: this.bizForm.get('last')!.value, phone: '', paid: false, name: this.bizForm.get('name')!.value, @@ -186,4 +190,12 @@ export class BusinessComponent implements OnInit { }); } + loginCheck(){ + this.ownerUpdate.subscribe((owner) => { + if(owner.paid) { + this.router.navigate(['/shop']); + } + }); + } + } diff --git a/src/app/header/header.component.html b/src/app/header/header.component.html index 9be405b..df9e337 100644 --- a/src/app/header/header.component.html +++ b/src/app/header/header.component.html @@ -8,4 +8,7 @@

Last block:

{{heightUpdate | async}}

+ + + diff --git a/src/app/header/header.component.ts b/src/app/header/header.component.ts index 09d04e9..a20f169 100644 --- a/src/app/header/header.component.ts +++ b/src/app/header/header.component.ts @@ -1,7 +1,9 @@ import {Component, OnInit, OnDestroy} from '@angular/core'; import { MatDialog, MatDialogConfig} from '@angular/material/dialog'; import {FullnodeService} from '../fullnode.service'; +import { Router } from '@angular/router'; import { UserService } from '../user.service'; +import { LogoutComponent } from '../logout/logout.component'; import {Subscription, Observable} from 'rxjs'; import {Owner} from '../owner.model'; @@ -44,7 +46,8 @@ export class HeaderComponent implements OnInit, OnDestroy { constructor( public fullnodeService: FullnodeService, public userService: UserService, - private dialog: MatDialog + private dialog: MatDialog, + private router: Router ){ this.heightUpdate = fullnodeService.heightUpdate; this.uZaddrUpdate = userService.uZaddrUpdate; @@ -64,4 +67,23 @@ export class HeaderComponent implements OnInit, OnDestroy { getCurrency(){ return this.owner.currency.toUpperCase(); } + + logout(){ + const dialogConfig = new MatDialogConfig(); + + dialogConfig.disableClose = true; + dialogConfig.autoFocus = true; + + const dialogRef = this.dialog.open(LogoutComponent, dialogConfig); + dialogRef.afterClosed().subscribe(val => { + if(val){ + console.log('Logout!'); + this.userService.deleteUser().subscribe(UserResponse => { + console.log('Rerouting'); + this.userService.findUser(); + this.router.navigate(['/login']); + }); + } + }); + } } diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index 84e9bf6..d5209b0 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -35,7 +35,7 @@ export class LoginComponent implements OnInit, AfterViewInit { address: '', session: '', blocktime: 0, - expiration: 0, + expired: false, pin: '', validated: false }; diff --git a/src/app/logout/logout.component.css b/src/app/logout/logout.component.css new file mode 100644 index 0000000..eeb06e6 --- /dev/null +++ b/src/app/logout/logout.component.css @@ -0,0 +1,3 @@ +* { + font-family: 'Spartan', sans-serif; +} diff --git a/src/app/logout/logout.component.html b/src/app/logout/logout.component.html new file mode 100644 index 0000000..1e8f626 --- /dev/null +++ b/src/app/logout/logout.component.html @@ -0,0 +1,28 @@ +

Logout?

+ + +
+

Are you sure you want to disconnect this device from ZGo?

+

You will have to re-link your device to ZGo via Zcash shielded memo if you want to access your shop again.

+
+
+ + + + + + + + +
+ + + + + +
+
diff --git a/src/app/logout/logout.component.spec.ts b/src/app/logout/logout.component.spec.ts new file mode 100644 index 0000000..2f92d47 --- /dev/null +++ b/src/app/logout/logout.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LogoutComponent } from './logout.component'; + +describe('LogoutComponent', () => { + let component: LogoutComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LogoutComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(LogoutComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/logout/logout.component.ts b/src/app/logout/logout.component.ts new file mode 100644 index 0000000..eb13e88 --- /dev/null +++ b/src/app/logout/logout.component.ts @@ -0,0 +1,26 @@ +import { Component, OnInit } from '@angular/core'; +import { MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog'; + +@Component({ + selector: 'app-logout', + templateUrl: './logout.component.html', + styleUrls: ['./logout.component.css'] +}) +export class LogoutComponent implements OnInit { + + constructor( + private dialogRef: MatDialogRef + ) { } + + ngOnInit(): void { + } + + confirm() { + this.dialogRef.close(true); + } + + close() { + this.dialogRef.close(false); + } + +} diff --git a/src/app/user.model.ts b/src/app/user.model.ts index bf43ae3..d555e82 100644 --- a/src/app/user.model.ts +++ b/src/app/user.model.ts @@ -3,7 +3,7 @@ export interface User { address: string; session: string; blocktime: number; - expiration: number; + expired: boolean; pin: string; validated: boolean; } diff --git a/src/app/user.service.ts b/src/app/user.service.ts index d98abdf..d4796e5 100644 --- a/src/app/user.service.ts +++ b/src/app/user.service.ts @@ -15,7 +15,7 @@ export class UserService{ address: '', session: '', blocktime: 0, - expiration: 0, + expired: false, pin: '', validated: false }, @@ -98,6 +98,16 @@ export class UserService{ this._userUpdated.next(Object.assign({}, this.dataStore).user); this.getOwner(Object.assign({},this.dataStore.user).address); } else { + this.dataStore.user = { + address: '', + session: '', + blocktime: 0, + expired: false, + pin: '', + validated: false + }; + this._uZaddrUpdated.next(Object.assign({},this.dataStore).user.address); + this._userUpdated.next(Object.assign({}, this.dataStore).user); console.log('US: Did not find user'); } }); @@ -184,13 +194,14 @@ export class UserService{ return obs; } - hasOwner() { - return this.uZaddr === this.oZaddr; + deleteUser() { + let obs = this.http.delete<{message: string}>(this.beUrl+'api/user/'+this.dataStore.user._id, {headers: this.reqHeaders }); + + obs.subscribe(UserResponse => { + console.log('User delete request sent.'); + this.findUser(); + }); + + return obs; } - - getNameUpdateListener() { - return this.uNameUpdated; - } - - } diff --git a/src/app/viewer/viewer.component.ts b/src/app/viewer/viewer.component.ts index 67ec89a..b1fd217 100644 --- a/src/app/viewer/viewer.component.ts +++ b/src/app/viewer/viewer.component.ts @@ -24,7 +24,7 @@ export class ViewerComponent implements OnInit { address: '', session: '', blocktime: 0, - expiration: 0, + expired: false, pin: '', validated: false }; @@ -115,11 +115,17 @@ export class ViewerComponent implements OnInit { } loginCheck(){ - var today = new Date().getTime() / 1000; - //console.log('User check', this.user.validated); - if (!this.owner.paid || !this.user.validated) { - console.log('Log in expired!'); - this.router.navigate(['/login']); - } + this.userService.findUser(); + this.ownerUpdate.subscribe((owner) => { + this.owner = owner; + this.userUpdate.subscribe((user) => { + this.user = user; + console.log('Viewer loginCheck', this.user); + if (!this.owner.paid || !this.user.validated || this.user.expired) { + console.log('Log in expired!'); + this.router.navigate(['/login']); + } + }); + }); } }