diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 651b7b3..2914e5f 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,10 +1,11 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { CheckTokenCanActivate } from './services/auth/auth.service'; export const routes: Routes = [ { path: 'auth', loadChildren: () => import('./auth/auth.module').then(m => m.AuthModule) }, - { path: 'feed', loadChildren: () => import('./feed/feed.module').then(m => m.FeedModule) }, - { path: 'user', loadChildren: () => import('./user/user.module').then(m => m.UserModule) }, + { path: 'feed', loadChildren: () => import('./feed/feed.module').then(m => m.FeedModule), canActivate: [CheckTokenCanActivate] }, + { path: 'user', loadChildren: () => import('./user/user.module').then(m => m.UserModule), canActivate: [CheckTokenCanActivate] }, { path: '', redirectTo: 'feed', pathMatch: 'full'} ]; diff --git a/src/app/auth/login/login.component.ts b/src/app/auth/login/login.component.ts index 55c3ad7..9aef1cb 100644 --- a/src/app/auth/login/login.component.ts +++ b/src/app/auth/login/login.component.ts @@ -1,24 +1,36 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; import { Router } from '@angular/router'; +import { AuthService } from '../../services/auth/auth.service'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.scss', '../auth.component.scss'] }) -export class LoginComponent { +export class LoginComponent implements OnInit { loginForm = new FormGroup({ username: new FormControl(''), password: new FormControl('') }); - constructor(private router: Router) { + constructor(private router: Router, private auth: AuthService) { this.loginForm.addValidators([Validators.required]); } + ngOnInit(): void { + this.auth.getToken().then(()=> { this.router.navigateByUrl("/feed") }) + } + login() { - if (this.loginForm.valid) this.router.navigateByUrl("/feed"); - else alert("missing username or password"); + if (this.loginForm.valid) + this.auth.login( + this.loginForm.get('username')?.value as String, + this.loginForm.get('password')?.value as String + ) + .then(()=>{ this.router.navigateByUrl("/feed") }) + .catch(()=>{ alert("wrong username or password") }); + else + alert("missing username or password"); } } diff --git a/src/app/auth/register/register.component.ts b/src/app/auth/register/register.component.ts index dd8a270..5b2ea7a 100644 --- a/src/app/auth/register/register.component.ts +++ b/src/app/auth/register/register.component.ts @@ -1,5 +1,7 @@ import { Component } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { AuthService } from '../../services/auth/auth.service'; +import { Router } from '@angular/router'; @Component({ selector: 'app-register', @@ -13,11 +15,21 @@ export class RegisterComponent { rePassword: new FormControl('') }); - constructor() { + constructor(private router: Router, private auth: AuthService) { this.registerForm.addValidators([Validators.required, Validators.minLength(3)]); } register() { - if (!this.registerForm.valid) alert("failed to register"); + if (this.registerForm.valid) + this.auth.register( + this.registerForm.get('username')?.value as String, + this.registerForm.get('password')?.value as String, + this.registerForm.get('rePassword')?.value as String, + ) + .then(()=> { this.router.navigateByUrl('/auth/login') }) + .catch(()=> { alert('failed to register') }); + // TODO: better error messages + else + alert("failed to register"); } } diff --git a/src/app/services/auth/auth.service.spec.ts b/src/app/services/auth/auth.service.spec.ts new file mode 100644 index 0000000..f1251ca --- /dev/null +++ b/src/app/services/auth/auth.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { AuthService } from './auth.service'; + +describe('AuthService', () => { + let service: AuthService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AuthService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/auth/auth.service.ts b/src/app/services/auth/auth.service.ts new file mode 100644 index 0000000..66b0be9 --- /dev/null +++ b/src/app/services/auth/auth.service.ts @@ -0,0 +1,70 @@ +import { Injectable, inject } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivateFn, GuardResult, MaybeAsync, Router, RouterStateSnapshot } from '@angular/router'; + +@Injectable({ + providedIn: 'root' +}) +export class AuthService { + token?: String; + + constructor(private router: Router) { } + + checkAllowed() { + // TODO: check if the token is still valid + if (this.token) + return true; + else { + this.router.navigateByUrl('/auth/login'); + return false; + } + } + + getToken(): Promise { + // TODO: check if the token is still valid + return new Promise((resolve, reject) => { + if (this.token) + resolve(this.token); + else + reject(); + }); + } + + login(username: String, password: String): Promise { + return new Promise((resolve, reject) => { + // TODO: authenticate + if (username === "test" && password === "test") { + this.token = "valid_token"; + resolve(true); + } + else { + this.token = undefined; + reject(); + } + }); + } + + logout(): Promise { + return new Promise((resolve, reject) => { + // TODO: logout + this.token = undefined; + resolve(true); + }); + } + + register(username: String, password: String, rePassword: String): Promise { + return new Promise((resolve, reject) => { + // TODO: register + if (username !== "test" && password === rePassword) + resolve(true); + else + reject(); + }); + } +} + +export const CheckTokenCanActivate: CanActivateFn = ( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot +) => { + return inject(AuthService).checkAllowed(); +} \ No newline at end of file diff --git a/src/app/shared/side-menu/side-menu.component.html b/src/app/shared/side-menu/side-menu.component.html index a251418..e822e79 100644 --- a/src/app/shared/side-menu/side-menu.component.html +++ b/src/app/shared/side-menu/side-menu.component.html @@ -2,4 +2,5 @@ + \ No newline at end of file diff --git a/src/app/shared/side-menu/side-menu.component.ts b/src/app/shared/side-menu/side-menu.component.ts index 95aec5a..e1b7787 100644 --- a/src/app/shared/side-menu/side-menu.component.ts +++ b/src/app/shared/side-menu/side-menu.component.ts @@ -1,5 +1,6 @@ import { Component } from '@angular/core'; -import { RouterModule } from '@angular/router'; +import { Router, RouterModule } from '@angular/router'; +import { AuthService } from '../../services/auth/auth.service'; @Component({ selector: 'app-side-menu', @@ -9,5 +10,11 @@ import { RouterModule } from '@angular/router'; styleUrl: './side-menu.component.scss' }) export class SideMenuComponent { + constructor(private router: Router, private auth: AuthService) { } + logout() { + this.auth.logout() + .then(() => { this.router.navigateByUrl('/auth/login') }) + .catch(() => { alert('failed to log out') }); + } } diff --git a/src/app/user/user-routing.module.ts b/src/app/user/user-routing.module.ts index 3a55d86..be8ad2a 100644 --- a/src/app/user/user-routing.module.ts +++ b/src/app/user/user-routing.module.ts @@ -2,7 +2,10 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { UserComponent } from './user.component'; -const routes: Routes = [{ path: '', component: UserComponent }]; +const routes: Routes = [ + { path: '', component: UserComponent }, + { path: ':username', component: UserComponent } +]; @NgModule({ imports: [RouterModule.forChild(routes)],