diff --git a/client/src/app/app.routes.ts b/client/src/app/app.routes.ts index 19c6dfd..55abc21 100644 --- a/client/src/app/app.routes.ts +++ b/client/src/app/app.routes.ts @@ -3,12 +3,13 @@ import { ScreenSend } from './screens/screen-send/screen-send'; import { ScreenReceive } from './screens/screen-receive/screen-receive'; import { ScreenProfile } from './screens/screen-profile/screen-profile'; import { ScreenLogin } from './screens/screen-login/screen-login'; +import { authGuard } from './services/auth-guard'; export const routes: Routes = [ { path: '', pathMatch:'full', - redirectTo: '/send' + redirectTo: '/send', }, { path: 'login', @@ -17,13 +18,16 @@ export const routes: Routes = [ { path:'send', component: ScreenSend, + canActivate: [authGuard], }, { path:'receive', component: ScreenReceive, + canActivate: [authGuard], }, { path:'profile', component: ScreenProfile, + canActivate: [authGuard], }, ]; diff --git a/client/src/app/screens/screen-login/screen-login.ts b/client/src/app/screens/screen-login/screen-login.ts index 15ea6ca..fbef41f 100644 --- a/client/src/app/screens/screen-login/screen-login.ts +++ b/client/src/app/screens/screen-login/screen-login.ts @@ -1,7 +1,7 @@ import { CommonModule } from '@angular/common'; import { Component } from '@angular/core'; import { Validators, FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Form } from '@angular/forms'; -import { Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { APIService } from '../../services/api'; @@ -21,6 +21,7 @@ export class ScreenLogin { constructor( private api: APIService, private router: Router, + private route: ActivatedRoute, private fb: FormBuilder, ) { this.loginForm = this.fb.group({ @@ -36,13 +37,15 @@ export class ScreenLogin { this.api.login(this.loginForm.value.username, this.loginForm.value.password).subscribe({ next: () => { - this.router.navigate(['']); + const returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; + this.router.navigateByUrl(returnUrl); }, error: (err) => { this.error = err.error?.message || 'Login failed. Please try again.'; this.loading = false; } }); + this.api.checkAuthStatus().subscribe(); } } diff --git a/client/src/app/services/api.ts b/client/src/app/services/api.ts index 121bdda..69007ba 100644 --- a/client/src/app/services/api.ts +++ b/client/src/app/services/api.ts @@ -23,7 +23,7 @@ export class APIService { return this.http.post(this.apiUrl + '/auth/logout', {}); } checkAuthStatus(): Observable { - return this.http.get(`${this.apiUrl}/auth/status`, { withCredentials: true }).pipe( + return this.http.get(`${this.apiUrl}/auth/status`, { withCredentials: true}).pipe( map(() => true), catchError(() => of(false)), tap({ diff --git a/client/src/app/services/auth-guard.spec.ts b/client/src/app/services/auth-guard.spec.ts new file mode 100644 index 0000000..0f21aa3 --- /dev/null +++ b/client/src/app/services/auth-guard.spec.ts @@ -0,0 +1,17 @@ +import { TestBed } from '@angular/core/testing'; +import { CanActivateFn } from '@angular/router'; + +import { authGuard } from './auth-guard'; + +describe('authGuard', () => { + const executeGuard: CanActivateFn = (...guardParameters) => + TestBed.runInInjectionContext(() => authGuard(...guardParameters)); + + beforeEach(() => { + TestBed.configureTestingModule({}); + }); + + it('should be created', () => { + expect(executeGuard).toBeTruthy(); + }); +}); diff --git a/client/src/app/services/auth-guard.ts b/client/src/app/services/auth-guard.ts new file mode 100644 index 0000000..a0dad63 --- /dev/null +++ b/client/src/app/services/auth-guard.ts @@ -0,0 +1,20 @@ +import { inject } from '@angular/core'; +import { CanActivateFn, Router } from '@angular/router'; +import { APIService } from './api'; +import { map } from 'rxjs/operators'; + +export const authGuard: CanActivateFn = (route, state) => { + const api = inject(APIService); + const router = inject(Router); + + return api.isAuthenticated$.pipe( + map((isAuthenticated) => { + if (isAuthenticated) { + return true; + } else { + router.navigate(['/login'], { queryParams: { returnUrl: state.url } }); + return false; + } + }) + ); +}; diff --git a/server/src/routes/auth.ts b/server/src/routes/auth.ts index 42991a8..abccbce 100644 --- a/server/src/routes/auth.ts +++ b/server/src/routes/auth.ts @@ -1,6 +1,7 @@ import express, { Request } from 'express'; import { logger } from '../util/logging'; import User from '../model/user'; +import { JWT, JWK } from 'ts-jose'; const router = express.Router(); @@ -36,7 +37,6 @@ router.post('/logout', (req, res) => { }); router.get('/status', (req, res) => { - console.log(req.cookies); if (isAuthenticated(req)){ return res.status(200).json({authenticated: true}); @@ -49,4 +49,8 @@ function isAuthenticated(req: Request){ return req.cookies.jwt } +function getJWT(user: User){ + +} + export default router;