diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index e776fab..7e9a258 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -57,6 +57,17 @@ jobs: source: "./docker-compose.yml" target: /home/${{ vars.VM_USERNAME }}/${{ github.repository }} + - name: Create Environment File + env: + ANGULAR_APP_API_KEY: ${{ secrets.ANGELOS_APP_API_KEY }} + run: | + echo "export const environment = { + production: true, + angelosUrl: '/api/v1/question/chat', + angelosToken: '/api/token', + angelosAppApiKey: '${ANGELOS_APP_API_KEY}' + };" > src/environments/environment.prod.ts + - name: SSH to VM and Execute Docker-Compose Up uses: appleboy/ssh-action@v1.0.3 with: diff --git a/nginx.conf b/nginx.conf index 7774481..8281bfe 100644 --- a/nginx.conf +++ b/nginx.conf @@ -39,6 +39,7 @@ server { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Internal-Access "true"; } error_page 500 502 503 504 /50x.html; diff --git a/src/app/services/auth.service.spec.ts b/src/app/services/auth.service.spec.ts new file mode 100644 index 0000000..f1251ca --- /dev/null +++ b/src/app/services/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.service.ts b/src/app/services/auth.service.ts new file mode 100644 index 0000000..bf69506 --- /dev/null +++ b/src/app/services/auth.service.ts @@ -0,0 +1,31 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable, tap } from 'rxjs'; +import { environment } from '../../environments/environment'; + +export interface AuthResponse { + access_token: string; + token_type: string; +} + +@Injectable({ + providedIn: 'root' +}) +export class AuthService { + + constructor(private http: HttpClient) { } + + login(): Observable { + const headers = new HttpHeaders().set('x-api-key', environment.angelosAppApiKey); + return this.http.post(environment.angelosToken, { headers }).pipe( + tap((response: AuthResponse) => { + sessionStorage.setItem('access_token', response.access_token); + }) + ); + } + + // Method to retrieve the stored token + public getToken(): string | null { + return sessionStorage.getItem('access_token'); + } +} diff --git a/src/app/services/chatbot.service.ts b/src/app/services/chatbot.service.ts index 964d709..ff416ec 100644 --- a/src/app/services/chatbot.service.ts +++ b/src/app/services/chatbot.service.ts @@ -1,17 +1,37 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { ChatMessage } from '../chat/chat.component'; -import { Observable } from 'rxjs'; +import { Observable, switchMap } from 'rxjs'; import { environment } from '../../environments/environment'; +import { AuthService } from './auth.service'; @Injectable({ providedIn: 'root' }) export class ChatbotService { - constructor(private http: HttpClient) { } + constructor(private http: HttpClient, private authService: AuthService) { } + + sendBotRequest(token: string | null, chatHistory: ChatMessage[], study_program: string): Observable { + const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`); + return this.http.post(environment.angelosUrl, + { messages: chatHistory, study_program: study_program }, + { headers } + ); + } getBotResponse(chatHistory: ChatMessage[], study_program: string): Observable { - return this.http.post(environment.angelosUrl, { messages: chatHistory, study_program: study_program }); + const token = this.authService.getToken(); + if (token) { + return this.sendBotRequest(token, chatHistory, study_program); + } else { + // Login if no token is stored, then proceed with the bot request + return this.authService.login().pipe( + switchMap(() => { + const newToken = this.authService.getToken(); + return this.sendBotRequest(newToken, chatHistory, study_program); + }) + ); + } } } diff --git a/src/environments/environment.development.ts b/src/environments/environment.development.ts index 0187839..dfadc01 100644 --- a/src/environments/environment.development.ts +++ b/src/environments/environment.development.ts @@ -1,4 +1,6 @@ export const environment = { production: false, - angelosUrl: 'http://localhost:8000/api/v1/question/chat' -}; + angelosUrl: 'http://localhost:8000/api/v1/question/chat', + angelosToken: 'http://localhost:8000/api/token', + angelosAppApiKey: 'SOME_SECRET_KEY', +}; \ No newline at end of file diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 825fcab..e84e5f3 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -1,4 +1,6 @@ export const environment = { production: true, - angelosUrl: '/api/v1/question/chat' + angelosUrl: '/api/v1/question/chat', + angelosToken: '/api/token', + angelosAppApiKey: 'SOME_SECRET_KEY', };