diff --git a/.env.development b/.env.development index 544f6c74782f269b73faa0ddce97c1a256e0c9d5..4cb25fde8509fce62e08d1e175a641a72982296b 100644 --- a/.env.development +++ b/.env.development @@ -1 +1,2 @@ -VUE_APP_API="http://localhost:8080" \ No newline at end of file +VUE_APP_API="http://localhost:8080" +VUE_APP_KEYCLOAK_URL="https://catalogue-keycloak-dev.k8s.medina.esilab.org/auth" \ No newline at end of file diff --git a/.env.production b/.env.production index 58fe7e1d7ca02bb6eb4317b4fd58c47e1acaf3bb..9cc681bc0fed4661f3d749ea7e1ab162608bdc95 100644 --- a/.env.production +++ b/.env.production @@ -1 +1,2 @@ VUE_APP_API="<<CCE_API_URL>>" +VUE_APP_KEYCLOAK_URL="<<KEYCLOAK_URL>>" diff --git a/entrypoint.sh b/entrypoint.sh index 7c3eb90e209ec4596bef384b6141e31064c3d40a..d884d569c44a625dc60c5a572a035d24b86b4803 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,5 +1,6 @@ URL="${CCE_API_URL:-https://cce-api-dev.k8s.medina.esilab.org}" sed -i "s|<<CCE_API_URL>>|${CCE_API_URL}|g" /usr/share/nginx/html/js/app.*.js +sed -i "s|<<KEYCLOAK_URL>>|${KEYCLOAK_URL}|g" /usr/share/nginx/html/js/app.*.js nginx -g 'daemon off;' diff --git a/package.json b/package.json index f915868b71f40d0003ab62c9222867cc143fec6d..07be703a6994d4495dea98f0235e8705f551a89e 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "vue": "^3.2.47", "vue-axios": "^3.5.2", "vue-router": "^4.1.6", - "vuex": "^4.1.0" + "vuex": "^4.1.0", + "keycloak-js": "^21.0.2" }, "devDependencies": { "@babel/eslint-parser": "^7.21.3", diff --git a/src/main.js b/src/main.js index 44dab70dc31e5fbedf11f0fc9b660f958f73588b..82fcb860737d8f3d850098902c393e4fd1629729 100644 --- a/src/main.js +++ b/src/main.js @@ -1,21 +1,55 @@ -import { createApp } from "vue"; +import {createApp} from "vue"; import App from "./App.vue"; import router from "./router"; import store from "@/store"; import axios from "axios"; import VueAxios from "vue-axios"; +import Keycloak from "keycloak-js"; import BootstrapVueNext from "bootstrap-vue-next"; import "bootstrap/dist/css/bootstrap.css"; import "bootstrap-vue-next/dist/bootstrap-vue-next.css"; -import { dom } from "@fortawesome/fontawesome-svg-core"; +import {dom} from "@fortawesome/fontawesome-svg-core"; dom.watch(); import "@fortawesome/fontawesome-free/css/all.css"; -const app = createApp(App); -app.use(router); -app.use(store); -app.use(VueAxios, axios); -app.use(BootstrapVueNext); -app.mount("#app"); +let initOptions = { + url: process.env.VUE_APP_KEYCLOAK_URL, + realm: 'medina', + clientId: 'cce-frontend', + onLoad: 'login-required' +} + +let keycloak = new Keycloak(initOptions); + +keycloak.init({onLoad: initOptions.onLoad}).then((auth) => { + if (!auth) { + window.location.reload(); + } else { + axios.defaults.headers.common = { + 'Authorization': 'Bearer ' + keycloak.token + }; + + const app = createApp(App); + app.use(router); + app.use(store); + app.use(VueAxios, axios); + app.use(BootstrapVueNext); + app.mount("#app"); + } + + setInterval(() => { + keycloak.updateToken(300).then((refreshed) => { + if (!refreshed) { + console.warn('Token not refreshed, valid for ' + + Math.round(keycloak.tokenParsed.exp + keycloak.timeSkew - new Date().getTime() / 1000) + ' seconds'); + } + }).catch(() => { + console.error('Failed to refresh token') + }); + }, 300 * 1000) + +}).catch(() => { + console.error("Keycloak authentication failed"); +}); diff --git a/src/services/ApiService.js b/src/services/ApiService.js index bfad5be9d6fe12bde8c88111bd02defb7aa7d8ac..6c14148732c695afcccb463094b81f9c29797b82 100644 --- a/src/services/ApiService.js +++ b/src/services/ApiService.js @@ -1,13 +1,17 @@ -import api from "@/client/client"; +import axios from "axios"; + +const headers = { + "Content-Type": "application/json" +}; export const ApiService = { - getToeList() { - return api.get("/toeList"); - }, - getToeHistory(toeId) { - return api.get("/toes/" + toeId + "/listHistory"); - }, - getTreeByStateId(stateId) { - return api.get("/history/" + stateId); - }, + getToeList() { + return axios.get(process.env.VUE_APP_API + "/toeList", {headers}); + }, + getToeHistory(toeId) { + return axios.get(process.env.VUE_APP_API + "/toes/" + toeId + "/listHistory", {headers}); + }, + getTreeByStateId(stateId) { + return axios.get(process.env.VUE_APP_API + "/history/" + stateId, {headers}); + }, };