diff --git a/apiGateway/src/main/resources/application.yml b/apiGateway/src/main/resources/application.yml index c041e40..1c1e6ae 100644 --- a/apiGateway/src/main/resources/application.yml +++ b/apiGateway/src/main/resources/application.yml @@ -7,7 +7,7 @@ spring: oauth2: resourceserver: jwt: - issuer-uri: http://keycloak:8080/realms/e-library + issuer-uri: http://localhost:8181/realms/e-library jwk-set-uri: http://localhost:8181/realms/e-library/protocol/openid-connect/certs services: diff --git a/book-bazaar/package-lock.json b/book-bazaar/package-lock.json index d881649..f61482b 100644 --- a/book-bazaar/package-lock.json +++ b/book-bazaar/package-lock.json @@ -17,6 +17,8 @@ "@angular/platform-browser": "^20.3.0", "@angular/router": "^20.3.0", "@tailwindcss/postcss": "^4.1.16", + "keycloak-angular": "^20.0.0", + "keycloak-js": "^26.2.1", "rxjs": "~7.8.0", "tslib": "^2.3.0" }, @@ -639,6 +641,7 @@ "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.10.tgz", "integrity": "sha512-Z03cfH1jgQ7XMDJj4R8qAGqivcvhdG3wYBwaiN1K1ODBgPhbFKNeD4stKqYp7xBNtswmM2O2jMxrL/Djwju4Gg==", "license": "MIT", + "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -6859,6 +6862,32 @@ "node": ">=10" } }, + "node_modules/keycloak-angular": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/keycloak-angular/-/keycloak-angular-20.0.0.tgz", + "integrity": "sha512-p9ThVUN8TNz15M2dd11VRDdHzgEDRSSxvyRGtK4N45lTbfs52DeNK+YXcpgt8ZX0/YN27GjU9GjiB4odI4/A2Q==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.1" + }, + "peerDependencies": { + "@angular/common": "^20", + "@angular/core": "^20", + "@angular/router": "^20", + "keycloak-js": "^18 || ^19 || ^20 || ^21 || ^22 || ^23 || ^24 || ^25 || ^26", + "rxjs": "^7" + } + }, + "node_modules/keycloak-js": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.1.tgz", + "integrity": "sha512-bZt6fQj/TLBAmivXSxSlqAJxBx/knNZDQGJIW4ensGYGN4N6tUKV8Zj3Y7/LOV8eIpvWsvqV70fbACihK8Ze0Q==", + "license": "Apache-2.0", + "peer": true, + "workspaces": [ + "test" + ] + }, "node_modules/lightningcss": { "version": "1.30.2", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", diff --git a/book-bazaar/package.json b/book-bazaar/package.json index fe2ae82..5488764 100644 --- a/book-bazaar/package.json +++ b/book-bazaar/package.json @@ -31,6 +31,8 @@ "@angular/platform-browser": "^20.3.0", "@angular/router": "^20.3.0", "@tailwindcss/postcss": "^4.1.16", + "keycloak-angular": "^20.0.0", + "keycloak-js": "^26.2.1", "rxjs": "~7.8.0", "tslib": "^2.3.0" }, diff --git a/book-bazaar/public/hero-books-illustration.jpg b/book-bazaar/public/hero-books-illustration.jpg new file mode 100644 index 0000000..0037619 Binary files /dev/null and b/book-bazaar/public/hero-books-illustration.jpg differ diff --git a/book-bazaar/public/silent-check-sso.html b/book-bazaar/public/silent-check-sso.html new file mode 100644 index 0000000..96b3cf9 --- /dev/null +++ b/book-bazaar/public/silent-check-sso.html @@ -0,0 +1,8 @@ + + +
+ + + \ No newline at end of file diff --git a/book-bazaar/src/app/app.config.ts b/book-bazaar/src/app/app.config.ts index a4001de..f5b4220 100644 --- a/book-bazaar/src/app/app.config.ts +++ b/book-bazaar/src/app/app.config.ts @@ -1,14 +1,47 @@ -import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZonelessChangeDetection } from '@angular/core'; -import {provideRouter, withViewTransitions} from '@angular/router'; +import { ApplicationConfig, inject, provideAppInitializer, provideBrowserGlobalErrorListeners, provideZonelessChangeDetection } from '@angular/core'; +import { provideRouter, withViewTransitions } from '@angular/router'; import { routes } from './app.routes'; -import { provideHttpClient } from '@angular/common/http'; +import { provideHttpClient, withInterceptors } from '@angular/common/http'; +import { + provideKeycloak, + INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG, + includeBearerTokenInterceptor, + createInterceptorCondition +} from 'keycloak-angular'; export const appConfig: ApplicationConfig = { providers: [ provideBrowserGlobalErrorListeners(), provideZonelessChangeDetection(), provideRouter(routes, withViewTransitions()), - provideHttpClient(), + + provideHttpClient(withInterceptors([includeBearerTokenInterceptor])), + + provideKeycloak({ + config: { + url: 'http://localhost:8181', + realm: 'e-library', + clientId: 'e-library-client' + }, + initOptions: { + // 'check-sso': перевіряє сесію тихо. Якщо юзер залогінений - пускає, ні - лишає анонімом. + // 'login-required': відразу кидає на сторінку логіну (вам це НЕ підходить). + onLoad: 'check-sso', + silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html', + checkLoginIframe: false // Вимикаємо, щоб уникнути проблем з cookies у сучасних браузерах + }, + // Автоматично додавати токен (Bearer) до запитів + }), + { + provide: INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG, + useValue: [ + createInterceptorCondition({ + urlPattern: /^(http:\/\/localhost:9000|http:\/\/localhost:8080)(\/.*)?$/i, // Регулярка для ваших сервісів + bearerPrefix: 'Bearer' + }), + // Можна додати інші умови, якщо є інші бекенди + ] + } ] }; diff --git a/book-bazaar/src/app/components/book-card/book-card.html b/book-bazaar/src/app/components/book-card/book-card.html index e293b4e..54aa45f 100644 --- a/book-bazaar/src/app/components/book-card/book-card.html +++ b/book-bazaar/src/app/components/book-card/book-card.html @@ -1,43 +1,51 @@ - +Explore thousands of books, read reviews, and connect with fellow book - lovers in our digital library.
-+ Explore thousands of books, read authentic reviews, and connect with fellow book lovers in our digital library. +
+ +
+ Search through thousands of books and discover your next favorite read
-