merge design
This commit is contained in:
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@intlify/vite-plugin-vue-i18n": "^3.3.1",
|
"@intlify/vite-plugin-vue-i18n": "^3.3.1",
|
||||||
"@quasar/app-vite": "^1.8.0",
|
"@quasar/app-vite": "^1.8.5",
|
||||||
"@quasar/cli": "^2.4.0",
|
"@quasar/cli": "^2.4.0",
|
||||||
"@types/node": "^12.20.21",
|
"@types/node": "^12.20.21",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
const { configure } = require('quasar/wrappers');
|
const { configure } = require('quasar/wrappers');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const frontendPort = 8080;
|
||||||
|
|
||||||
module.exports = configure(function (/* ctx */) {
|
module.exports = configure(function (/* ctx */) {
|
||||||
return {
|
return {
|
||||||
@@ -67,7 +68,7 @@ module.exports = configure(function (/* ctx */) {
|
|||||||
|
|
||||||
//Defined in realm_export.json, initialize_keycloak.sh and quasar.config.js
|
//Defined in realm_export.json, initialize_keycloak.sh and quasar.config.js
|
||||||
PORT_KEYCLOAK:8083,
|
PORT_KEYCLOAK:8083,
|
||||||
PORT_FRONTEND:8080,
|
PORT_FRONTEND:frontendPort,
|
||||||
PORT_BACKEND:8081,
|
PORT_BACKEND:8081,
|
||||||
},
|
},
|
||||||
// rawDefine: {}
|
// rawDefine: {}
|
||||||
@@ -106,14 +107,15 @@ module.exports = configure(function (/* ctx */) {
|
|||||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
|
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
|
||||||
devServer: {
|
devServer: {
|
||||||
// https: true
|
// https: true
|
||||||
port: 8080, // default: 3000; changed to 8080 to match keycloak settings
|
port: frontendPort, // default: 3000; changed to 8080 to match keycloak settings
|
||||||
open: true, // opens browser window automatically
|
open: true, // opens browser window automatically
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://localhost:8080',
|
target: 'http://localhost:' + frontendPort,
|
||||||
changeOrigin: true
|
changeOrigin: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
|
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
|
||||||
|
|||||||
6
src/boot/pinia.ts
Normal file
6
src/boot/pinia.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { boot } from 'quasar/wrappers';
|
||||||
|
import { createPinia } from 'pinia';
|
||||||
|
|
||||||
|
export default boot(({ app }) => {
|
||||||
|
app.use(createPinia());
|
||||||
|
});
|
||||||
@@ -1,45 +1,43 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useKeycloakStore } from '../stores/keycloakStore';
|
|
||||||
import { defineComponent, onMounted, ref } from 'vue';
|
import { defineComponent, onMounted, ref } from 'vue';
|
||||||
import { useUserStore } from 'stores/user-store';
|
import { useUserStore } from 'stores/user-store';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
/*const protectedData = ref("");
|
import { ptpUser } from 'src/models';
|
||||||
const keycloakStore = useKeycloakStore();
|
|
||||||
|
|
||||||
function fetchProtectedData() {
|
|
||||||
const keycloak = keycloakStore.getKeycloak;
|
|
||||||
if(!keycloak){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let myHeaders = new Headers();
|
|
||||||
if(!keycloak.token){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
myHeaders.append("Authorization", "Bearer " + keycloak.token);
|
|
||||||
let requestOptons = {
|
|
||||||
headers: myHeaders,
|
|
||||||
};
|
|
||||||
fetch("localhost:"+ import.meta.env.PORT_BACKEND + "/api/protected", requestOptons)
|
|
||||||
.then((response) => response.text())
|
|
||||||
.then((data) => {
|
|
||||||
protectedData.value = data;
|
|
||||||
console.info("Protected data: ", data);
|
|
||||||
}).catch((e)=>console.error("Error fetching protected data: ", e));
|
|
||||||
}
|
|
||||||
onMounted(() => {
|
|
||||||
console.info("Protected component mounted");
|
|
||||||
fetchProtectedData();
|
|
||||||
});*/
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ProtectedData',
|
name: 'ProtectedData',
|
||||||
components: {},
|
components: {},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
return userStore;
|
const user = ref();
|
||||||
|
const userLoaded = ref(false);
|
||||||
|
const logout = () => {
|
||||||
|
userStore.logout();
|
||||||
|
router.push('/');
|
||||||
|
};
|
||||||
|
const users = ref([] as ptpUser[]);
|
||||||
|
const usersLoaded = ref(false);
|
||||||
|
const loadUsers = async() => {
|
||||||
|
await userStore.loadAllUsers();
|
||||||
|
usersLoaded.value = true;
|
||||||
|
users.value = userStore.users;
|
||||||
}
|
}
|
||||||
|
onMounted(async () => {
|
||||||
|
userLoaded.value = userStore.userLoaded;
|
||||||
|
user.value = userStore.user;
|
||||||
|
//users = await userStore.getAllUsers();
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
user,
|
||||||
|
userLoaded,
|
||||||
|
logout,
|
||||||
|
loadUsers,
|
||||||
|
users,
|
||||||
|
usersLoaded
|
||||||
|
};
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -52,6 +50,17 @@ export default defineComponent({
|
|||||||
<p>{{ user.username }}</p>
|
<p>{{ user.username }}</p>
|
||||||
<p>{{ user.keycloakID }}</p>
|
<p>{{ user.keycloakID }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
<q-btn @click="logout()" label="Logout"/>
|
||||||
|
<q-btn @click="loadUsers()" label="Print Users"/>
|
||||||
|
<div v-if="usersLoaded">
|
||||||
|
<p>Users:</p>
|
||||||
|
<div v-for="user in users" :key="user.keycloakID">
|
||||||
|
<p>{{ user.firstName }}</p>
|
||||||
|
<p>{{ user.lastName }}</p>
|
||||||
|
<p>{{ user.username }}</p>
|
||||||
|
<p>{{ user.keycloakID }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
50
src/main.ts
50
src/main.ts
@@ -3,60 +3,32 @@ import {createPinia} from 'pinia';
|
|||||||
|
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
|
|
||||||
import Keycloak, {type KeycloakConfig, type KeycloakInitOptions} from 'keycloak-js';
|
import Keycloak from 'keycloak-js';
|
||||||
import { useKeycloakStore } from 'stores/keycloakStore';
|
|
||||||
import {useUserStore} from 'stores/user-store';
|
import {useUserStore} from 'stores/user-store';
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
app.use(createPinia());
|
const pinia = createPinia();
|
||||||
|
app.use(pinia);
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialisierungsoptionen für Keycloak.
|
|
||||||
* @param url URL zu Keycloak, Port definiert in keycloak_init.sh und quasar.config.js-Datei. Müssen identisch sein!
|
|
||||||
* @param realm Name des Realms, hinterlegt in realm-export.json von Keycloak und quasar.config.js-Datei. Müssen identisch sein!
|
|
||||||
* @param clientId Name des Clients, hinterlegt in realm-export.json von Keycloak und quasar.config.js-Datei. Müssen identisch sein!
|
|
||||||
* @param onLoad = 'login-required': Hierdurch wird zum Aufrufen der ganzen Applikation ein login benötigt.
|
|
||||||
* @param redirectUri: URL, zu der nach dem Login weitergeleitet wird. Hierbei wird die Port des Frontends aus der .env-Datei verwendet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*const keycloak = new Keycloak({
|
|
||||||
url: 'http://localhost:8083/',
|
|
||||||
realm: 'PraxistransferKeycloak',
|
|
||||||
clientId: 'praxistransfer'
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("ICH WAR HIER");
|
const userStore = useUserStore();
|
||||||
|
const keycloak: Keycloak = await userStore.initKeycloak();
|
||||||
try {
|
|
||||||
const authenticated = await keycloak.init({
|
|
||||||
onLoad: 'login-required',
|
|
||||||
redirectUri: 'http://localhost:8080/'
|
|
||||||
}).then( (auth) => {
|
|
||||||
console.log("Authenticated :" + authenticated);
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(keycloak);
|
|
||||||
console.log(keycloak.subject);
|
|
||||||
|
|
||||||
// Anfrage ans Backend
|
// Anfrage ans Backend
|
||||||
const userStore = useUserStore();
|
|
||||||
|
|
||||||
if (keycloak.subject != null) {
|
if (keycloak.subject) {
|
||||||
|
userStore.keycloakId = keycloak.subject;
|
||||||
//userStore.loadPtpUsersByKeycloakID(keycloak.subject);
|
//userStore.loadPtpUsersByKeycloakID(keycloak.subject);
|
||||||
userStore.getPtpUserByKeycloakID(keycloak.subject);
|
await userStore.getPtpUserByKeycloakID(keycloak.subject);
|
||||||
/*console.log(userStore.userLoaded);
|
/*console.log(userStore.userLoaded);
|
||||||
if(userStore.userLoaded) {
|
if(userStore.userLoaded) {
|
||||||
console.log("Hier ist der Bruder: " + JSON.stringify(userStore.user));
|
console.log("Hier ist der Bruder: " + JSON.stringify(userStore.user));
|
||||||
}*/
|
}*/
|
||||||
/*userStore.loadPtpUsersByKeycloakID(keycloak.subject).then(user => {
|
userStore.loadPtpUsersByKeycloakID(keycloak.subject).then(user => {
|
||||||
console.log(JSON.stringify(user));
|
console.log(JSON.stringify(user));
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
console.log("hier ist was schlimmes passiert menno");
|
console.error("hier ist was schlimmes passiert menno");
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
import { store } from 'quasar/wrappers'
|
|
||||||
import { createPinia } from 'pinia'
|
|
||||||
import { Router } from 'vue-router';
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When adding new properties to stores, you should also
|
|
||||||
* extend the `PiniaCustomProperties` interface.
|
|
||||||
* @see https://pinia.vuejs.org/core-concepts/plugins.html#typing-new-store-properties
|
|
||||||
*/
|
|
||||||
declare module 'pinia' {
|
|
||||||
export interface PiniaCustomProperties {
|
|
||||||
readonly router: Router;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If not building with SSR mode, you can
|
|
||||||
* directly export the Store instantiation;
|
|
||||||
*
|
|
||||||
* The function below can be async too; either use
|
|
||||||
* async/await or return a Promise which resolves
|
|
||||||
* with the Store instance.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default store((/* { ssrContext } */) => {
|
|
||||||
const pinia = createPinia()
|
|
||||||
|
|
||||||
// You can add Pinia plugins here
|
|
||||||
// pinia.use(SomePiniaPlugin)
|
|
||||||
|
|
||||||
return pinia
|
|
||||||
})
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import type Keycloak from 'keycloak-js';
|
|
||||||
import { defineStore } from 'pinia';
|
|
||||||
//import api from 'axios';
|
|
||||||
|
|
||||||
export const useKeycloakStore = defineStore('keycloakStore', {
|
|
||||||
state: ()=>({
|
|
||||||
keycloak: null as Keycloak| null,
|
|
||||||
}),
|
|
||||||
getters: {
|
|
||||||
getKeycloak: (state) => state.keycloak,
|
|
||||||
},
|
|
||||||
actions:{
|
|
||||||
setKeycloak(keycloak: Keycloak): void {
|
|
||||||
this.keycloak = keycloak;
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,24 +1,24 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import {api} from 'boot/axios';
|
import { api } from 'src/boot/axios';
|
||||||
import { ptpUser, responseModel } from 'src/models';
|
import { ptpUser, responseModel } from 'src/models';
|
||||||
import Keycloak from 'keycloak-js';
|
import Keycloak, { KeycloakInitOptions, KeycloakLoginOptions } from 'keycloak-js';
|
||||||
|
|
||||||
export const useUserStore = defineStore('userStore', {
|
export const useUserStore = defineStore('userStore', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
user: {"keycloakID":null,"firstName":null,"lastName":null,"username":null},
|
user: null as ptpUser | null,
|
||||||
userLoaded: false,
|
userLoaded: false,
|
||||||
users: [] as ptpUser[],
|
users: [] as ptpUser[],
|
||||||
usersLoaded: false,
|
usersLoaded: false,
|
||||||
|
keycloak: null as Keycloak | null,
|
||||||
|
keycloakId: "",
|
||||||
|
users: [] as ptpUser[],
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {},
|
||||||
|
|
||||||
},
|
|
||||||
actions: {
|
actions: {
|
||||||
getPtpUserByKeycloakID(keycloakID : string) {
|
async getPtpUserByKeycloakID(keycloakID : string) {
|
||||||
this.loadPtpUsersByKeycloakID(keycloakID).then((response : responseModel) => {
|
await this.loadPtpUsersByKeycloakID(keycloakID).then((response : responseModel) => {
|
||||||
this.user = response.response;
|
this.user = response.response;
|
||||||
this.userLoaded = true;
|
this.userLoaded = true;
|
||||||
console.log("ich habe das gesetzt: " + JSON.stringify(this.user) + " / " + this.userLoaded);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async loadPtpUsersByKeycloakID(keycloakID : string) : Promise<responseModel> {
|
async loadPtpUsersByKeycloakID(keycloakID : string) : Promise<responseModel> {
|
||||||
@@ -32,6 +32,47 @@ export const useUserStore = defineStore('userStore', {
|
|||||||
},
|
},
|
||||||
async loadAllPtpUsers() {
|
async loadAllPtpUsers() {
|
||||||
return (await api.get("/users/user")).data;
|
return (await api.get("/users/user")).data;
|
||||||
|
},
|
||||||
|
async initKeycloak() {
|
||||||
|
/**
|
||||||
|
* Variablen sind in quasar.config.js definiert und werden hier verwendet.
|
||||||
|
* @param keycloakPort Port, auf dem Keycloak läuft, hinterlegt in docker-compose.yml
|
||||||
|
* @param frontendPort Port, auf dem das Frontend läuft, hinterlegt in quasar.config.js und realm-export.json von Keycloak für die Redirect-URL
|
||||||
|
* @param realm Name des Realms, hinterlegt in realm-export.json von Keycloak
|
||||||
|
* @param clientId Name des Clients, hinterlegt in realm-export.json von Keycloak
|
||||||
|
*/
|
||||||
|
const keycloakPort: string = "" + process.env.PORT_KEYCLOAK;
|
||||||
|
const frontendPort: string = "" + process.env.PORT_FRONTEND;
|
||||||
|
const realm : string= "" + process.env.KEYCLOAK_REALM;
|
||||||
|
const clientId: string = "" + process.env.KEYCLOAK_CLIENT_ID;
|
||||||
|
const keycloak: Keycloak = new Keycloak({
|
||||||
|
url: 'http://localhost:' + keycloakPort + '/',
|
||||||
|
realm: realm,
|
||||||
|
clientId: clientId
|
||||||
|
});
|
||||||
|
const initOptions: KeycloakInitOptions = {
|
||||||
|
onLoad: 'login-required', //erzwingt Login
|
||||||
|
redirectUri: 'http://localhost:' + frontendPort + '/',
|
||||||
|
checkLoginIframe: false,
|
||||||
|
locale: 'login-required',
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
await keycloak.init(initOptions).then( (auth: boolean): void => {
|
||||||
|
console.log("Authenticated: " + auth);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
this.keycloak = keycloak;
|
||||||
|
return keycloak;
|
||||||
|
},
|
||||||
|
async login() {
|
||||||
|
if(!this.keycloak){
|
||||||
|
await this.initKeycloak();
|
||||||
|
}else await this.keycloak?.login( {prompt: 'login'} as KeycloakLoginOptions);
|
||||||
|
},
|
||||||
|
async logout() {
|
||||||
|
window.location.href= 'http://localhost:' + process.env.PORT_KEYCLOAK + '/realms/' + process.env.KEYCLOAK_REALM + '/protocol/openid-connect/logout?post_logout_redirect_uri=http%3A%2F%2Flocalhost:' + process.env.PORT_FRONTEND + '&client_id=' + process.env.KEYCLOAK_CLIENT_ID;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user