diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..79b5594 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**/.DS_Store diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..2fdf6da --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1 @@ +blog.db diff --git a/backend/blog.db b/backend/blog.db index 0a59c2a..15e0e60 100644 Binary files a/backend/blog.db and b/backend/blog.db differ diff --git a/frontend/src/app/app.config.ts b/frontend/src/app/app.config.ts index 3c0cff3..ccf6af2 100644 --- a/frontend/src/app/app.config.ts +++ b/frontend/src/app/app.config.ts @@ -2,12 +2,19 @@ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter, withComponentInputBinding } from '@angular/router'; import { routes } from './app.routes'; -import { provideHttpClient } from '@angular/common/http'; +import { + HTTP_INTERCEPTORS, + provideHttpClient, + withInterceptors, + withInterceptorsFromDi, +} from '@angular/common/http'; +import { AuthInterceptor } from './shared/interceptors/auth.interceptor'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes, withComponentInputBinding()), - provideHttpClient(), + provideHttpClient(withInterceptorsFromDi()), + { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }, ], }; diff --git a/frontend/src/app/routes/admin/admin.component.ts b/frontend/src/app/routes/admin/admin.component.ts index f326132..3a0bebe 100644 --- a/frontend/src/app/routes/admin/admin.component.ts +++ b/frontend/src/app/routes/admin/admin.component.ts @@ -1,4 +1,4 @@ -import { Component, inject } from '@angular/core'; +import { Component, effect, inject } from '@angular/core'; import { PostEditorComponent } from '../../components/post-editor/post-editor.component'; import { NgFor } from '@angular/common'; import { PostsService } from '../../shared/services/posts.service'; diff --git a/frontend/src/app/routes/post/create-post/create-post.component.ts b/frontend/src/app/routes/post/create-post/create-post.component.ts index b032e08..5928d48 100644 --- a/frontend/src/app/routes/post/create-post/create-post.component.ts +++ b/frontend/src/app/routes/post/create-post/create-post.component.ts @@ -20,10 +20,6 @@ export class CreatePostComponent { }); constructor() { - effect(() => { - console.log('create', this.post()); - }); - setTimeout(() => { this.post.set({ ...this.post(), title: 'adf' }); }, 1000); diff --git a/frontend/src/app/shared/interceptors/auth.interceptor.spec.ts b/frontend/src/app/shared/interceptors/auth.interceptor.spec.ts new file mode 100644 index 0000000..7ab58db --- /dev/null +++ b/frontend/src/app/shared/interceptors/auth.interceptor.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { AuthInterceptor } from './auth.interceptor'; + +describe('AuthInterceptor', () => { + beforeEach(() => TestBed.configureTestingModule({ + providers: [ + AuthInterceptor + ] + })); + + it('should be created', () => { + const interceptor: AuthInterceptor = TestBed.inject(AuthInterceptor); + expect(interceptor).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/shared/interceptors/auth.interceptor.ts b/frontend/src/app/shared/interceptors/auth.interceptor.ts new file mode 100644 index 0000000..4720419 --- /dev/null +++ b/frontend/src/app/shared/interceptors/auth.interceptor.ts @@ -0,0 +1,29 @@ +import { inject, Injectable } from '@angular/core'; +import { + HttpRequest, + HttpHandler, + HttpEvent, + HttpInterceptor, +} from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { AuthService } from '../services/auth.service'; + +@Injectable() +export class AuthInterceptor implements HttpInterceptor { + private jwt = inject(AuthService).jwt; + + intercept( + req: HttpRequest, + next: HttpHandler, + ): Observable> { + const token = this.jwt(); + if (!token) { + return next.handle(req); + } + const reqWithAuth = req.clone({ + headers: req.headers.set('Authorization', `Bearer ${token}`), + }); + + return next.handle(reqWithAuth); + } +} diff --git a/frontend/src/app/shared/services/auth.service.ts b/frontend/src/app/shared/services/auth.service.ts index a0daa81..c6a0e12 100644 --- a/frontend/src/app/shared/services/auth.service.ts +++ b/frontend/src/app/shared/services/auth.service.ts @@ -61,8 +61,6 @@ export class AuthService { } login(user: User) { - console.log(user); - this.http .post(`${environment.apiRoot}/login`, user) .subscribe((res) => this.jwt.set(res.token)); diff --git a/frontend/src/app/shared/services/posts.service.ts b/frontend/src/app/shared/services/posts.service.ts index 79e96c4..82f3362 100644 --- a/frontend/src/app/shared/services/posts.service.ts +++ b/frontend/src/app/shared/services/posts.service.ts @@ -1,6 +1,7 @@ import { HttpClient } from '@angular/common/http'; import { computed, + effect, inject, Injectable, Signal, @@ -27,7 +28,9 @@ export class PostsService { .subscribe((res) => this.posts.set(new Map(res.map((p) => [p.id, p])))); } getPosts(): Signal { - return computed(() => Array.from(this.posts().values())); + return computed(() => + Array.from(this.posts().values()).sort((a, b) => b.id - a.id), + ); } getPost(id: number): Signal { @@ -38,7 +41,7 @@ export class PostsService { this.http .post(`${environment.apiRoot}/posts`, post) .subscribe((res) => { - this.posts.set(this.posts().set(res.id, res)); + this.posts.update((p) => new Map(p.set(res.id, res))); }); } }