MAJOR: Replace nuxt-openid-connect with official Keycloak JS adapter
- Remove problematic nuxt-openid-connect module that was causing OAuth issues - Install and implement official keycloak-js adapter for better reliability - Create new useKeycloak composable with proper token management - Update useUnifiedAuth to work with new Keycloak implementation - Fix authentication middleware to support both auth methods - Update login page to use new Keycloak login function - Clean up configuration and remove deprecated OIDC settings - This should resolve all the HTTP/HTTPS redirect and token exchange issues
This commit is contained in:
parent
bd8f1d9926
commit
a797c13867
|
|
@ -0,0 +1,129 @@
|
||||||
|
import type Keycloak from 'keycloak-js'
|
||||||
|
|
||||||
|
export const useKeycloak = () => {
|
||||||
|
const config = useRuntimeConfig()
|
||||||
|
const keycloak = ref<Keycloak | null>(null)
|
||||||
|
const isAuthenticated = ref(false)
|
||||||
|
const user = ref<any>(null)
|
||||||
|
const token = ref<string | null>(null)
|
||||||
|
const isInitialized = ref(false)
|
||||||
|
|
||||||
|
const initKeycloak = async () => {
|
||||||
|
if (process.server) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Dynamically import keycloak-js
|
||||||
|
const KeycloakModule = await import('keycloak-js')
|
||||||
|
const KeycloakConstructor = KeycloakModule.default
|
||||||
|
|
||||||
|
keycloak.value = new KeycloakConstructor({
|
||||||
|
url: config.public.keycloak.url,
|
||||||
|
realm: config.public.keycloak.realm,
|
||||||
|
clientId: config.public.keycloak.clientId,
|
||||||
|
})
|
||||||
|
|
||||||
|
const authenticated = await keycloak.value.init({
|
||||||
|
onLoad: 'check-sso',
|
||||||
|
silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html',
|
||||||
|
checkLoginIframe: false, // Disable iframe checks for better compatibility
|
||||||
|
})
|
||||||
|
|
||||||
|
isAuthenticated.value = authenticated
|
||||||
|
isInitialized.value = true
|
||||||
|
|
||||||
|
if (authenticated && keycloak.value.token) {
|
||||||
|
token.value = keycloak.value.token || null
|
||||||
|
user.value = {
|
||||||
|
id: keycloak.value.subject,
|
||||||
|
username: keycloak.value.tokenParsed?.preferred_username,
|
||||||
|
email: keycloak.value.tokenParsed?.email,
|
||||||
|
firstName: keycloak.value.tokenParsed?.given_name,
|
||||||
|
lastName: keycloak.value.tokenParsed?.family_name,
|
||||||
|
fullName: keycloak.value.tokenParsed?.name,
|
||||||
|
roles: keycloak.value.tokenParsed?.realm_access?.roles || [],
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up token refresh
|
||||||
|
keycloak.value.onTokenExpired = () => {
|
||||||
|
keycloak.value?.updateToken(30).then((refreshed) => {
|
||||||
|
if (refreshed) {
|
||||||
|
token.value = keycloak.value?.token || null
|
||||||
|
console.log('Token refreshed')
|
||||||
|
} else {
|
||||||
|
console.log('Token still valid')
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
console.log('Failed to refresh token')
|
||||||
|
logout()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return authenticated
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to initialize Keycloak:', error)
|
||||||
|
isInitialized.value = true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const login = async () => {
|
||||||
|
if (!keycloak.value) {
|
||||||
|
await initKeycloak()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keycloak.value) {
|
||||||
|
try {
|
||||||
|
await keycloak.value.login({
|
||||||
|
redirectUri: window.location.origin + '/dashboard'
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Login failed:', error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logout = async () => {
|
||||||
|
if (keycloak.value) {
|
||||||
|
try {
|
||||||
|
await keycloak.value.logout({
|
||||||
|
redirectUri: window.location.origin
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Logout failed:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear local state
|
||||||
|
isAuthenticated.value = false
|
||||||
|
user.value = null
|
||||||
|
token.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
const getToken = () => {
|
||||||
|
return token.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasRole = (role: string) => {
|
||||||
|
return user.value?.roles?.includes(role) || false
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasAnyRole = (roles: string[]) => {
|
||||||
|
return roles.some(role => hasRole(role))
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
keycloak: readonly(keycloak),
|
||||||
|
isAuthenticated: readonly(isAuthenticated),
|
||||||
|
user: readonly(user),
|
||||||
|
token: readonly(token),
|
||||||
|
isInitialized: readonly(isInitialized),
|
||||||
|
initKeycloak,
|
||||||
|
login,
|
||||||
|
logout,
|
||||||
|
getToken,
|
||||||
|
hasRole,
|
||||||
|
hasAnyRole,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,13 +11,13 @@ export const useUnifiedAuth = () => {
|
||||||
// Get both auth systems
|
// Get both auth systems
|
||||||
const directusAuth = useDirectusAuth();
|
const directusAuth = useDirectusAuth();
|
||||||
const directusUser = useDirectusUser();
|
const directusUser = useDirectusUser();
|
||||||
const oidc = useOidc();
|
const keycloak = useKeycloak();
|
||||||
|
|
||||||
// Create unified user object
|
// Create unified user object
|
||||||
const user = computed<UnifiedUser | null>(() => {
|
const user = computed<UnifiedUser | null>(() => {
|
||||||
// Check Keycloak user first
|
// Check Keycloak user first
|
||||||
if (oidc.user?.value) {
|
if (keycloak.user.value) {
|
||||||
const keycloakUser = oidc.user.value;
|
const keycloakUser = keycloak.user.value;
|
||||||
// Construct name from firstName and lastName if available
|
// Construct name from firstName and lastName if available
|
||||||
let name = keycloakUser.name;
|
let name = keycloakUser.name;
|
||||||
if (!name && (keycloakUser.given_name || keycloakUser.family_name)) {
|
if (!name && (keycloakUser.given_name || keycloakUser.family_name)) {
|
||||||
|
|
@ -58,7 +58,7 @@ export const useUnifiedAuth = () => {
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
if (user.value?.authSource === 'keycloak') {
|
if (user.value?.authSource === 'keycloak') {
|
||||||
// Keycloak logout
|
// Keycloak logout
|
||||||
await oidc.logout();
|
await keycloak.logout();
|
||||||
} else if (user.value?.authSource === 'directus') {
|
} else if (user.value?.authSource === 'directus') {
|
||||||
// Directus logout
|
// Directus logout
|
||||||
await directusAuth.logout();
|
await directusAuth.logout();
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,14 @@ export default defineNuxtRouteMiddleware(async (to) => {
|
||||||
const isAuthRequired = to.meta.auth !== false;
|
const isAuthRequired = to.meta.auth !== false;
|
||||||
|
|
||||||
// Check Keycloak auth first
|
// Check Keycloak auth first
|
||||||
const oidc = useOidc();
|
const keycloak = useKeycloak();
|
||||||
if (oidc.isLoggedIn) {
|
|
||||||
|
// Initialize Keycloak if not already initialized
|
||||||
|
if (!keycloak.isInitialized.value) {
|
||||||
|
await keycloak.initKeycloak();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keycloak.isAuthenticated.value) {
|
||||||
// User authenticated with Keycloak
|
// User authenticated with Keycloak
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ export default defineNuxtConfig({
|
||||||
ssr: false,
|
ssr: false,
|
||||||
compatibilityDate: "2024-11-01",
|
compatibilityDate: "2024-11-01",
|
||||||
devtools: { enabled: true },
|
devtools: { enabled: true },
|
||||||
modules: ["nuxt-directus", "nuxt-openid-connect", "vuetify-nuxt-module", "@vite-pwa/nuxt"],
|
modules: ["nuxt-directus", "vuetify-nuxt-module", "@vite-pwa/nuxt"],
|
||||||
app: {
|
app: {
|
||||||
head: {
|
head: {
|
||||||
titleTemplate: "%s • Port Nimara Portal",
|
titleTemplate: "%s • Port Nimara Portal",
|
||||||
|
|
@ -122,35 +122,10 @@ export default defineNuxtConfig({
|
||||||
directus: {
|
directus: {
|
||||||
url: "https://cms.portnimara.dev",
|
url: "https://cms.portnimara.dev",
|
||||||
},
|
},
|
||||||
},
|
keycloak: {
|
||||||
},
|
url: "https://auth.portnimara.dev",
|
||||||
openidConnect: {
|
realm: "client-portal",
|
||||||
addPlugin: true,
|
clientId: "client-portal",
|
||||||
op: {
|
|
||||||
issuer: process.env.KEYCLOAK_ISSUER || "https://auth.portnimara.dev/realms/client-portal",
|
|
||||||
clientId: process.env.KEYCLOAK_CLIENT_ID || "client-portal",
|
|
||||||
clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!, // Environment variable must be set
|
|
||||||
callbackUrl: "", // Deprecated in v0.8.0+ but required by types - module uses /oidc/cb automatically
|
|
||||||
scope: ["openid", "email", "profile"],
|
|
||||||
},
|
|
||||||
config: {
|
|
||||||
debug: true, // Enable debug mode to see what's happening
|
|
||||||
response_type: "code",
|
|
||||||
secret: process.env.OIDC_SESSION_SECRET || "default-session-secret-change-in-production",
|
|
||||||
cookie: {
|
|
||||||
loginName: "keycloak-login",
|
|
||||||
},
|
|
||||||
cookiePrefix: "keycloak._",
|
|
||||||
cookieEncrypt: true,
|
|
||||||
cookieEncryptKey: process.env.OIDC_ENCRYPT_KEY || "default-encrypt-key-change-in-prod",
|
|
||||||
cookieEncryptIV: process.env.OIDC_ENCRYPT_IV || "default-iv-12345",
|
|
||||||
cookieEncryptALGO: "aes-256-cbc",
|
|
||||||
cookieMaxAge: 24 * 60 * 60, // 1 day
|
|
||||||
cookieFlags: {
|
|
||||||
access_token: {
|
|
||||||
httpOnly: true,
|
|
||||||
secure: process.env.NODE_ENV === 'production',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
"@vite-pwa/nuxt": "^0.10.6",
|
"@vite-pwa/nuxt": "^0.10.6",
|
||||||
"formidable": "^3.5.4",
|
"formidable": "^3.5.4",
|
||||||
"imap": "^0.8.19",
|
"imap": "^0.8.19",
|
||||||
|
"keycloak-js": "^26.2.0",
|
||||||
"libphonenumber-js": "^1.12.9",
|
"libphonenumber-js": "^1.12.9",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mailparser": "^3.7.3",
|
"mailparser": "^3.7.3",
|
||||||
|
|
@ -20,7 +21,6 @@
|
||||||
"nodemailer": "^7.0.3",
|
"nodemailer": "^7.0.3",
|
||||||
"nuxt": "^3.15.4",
|
"nuxt": "^3.15.4",
|
||||||
"nuxt-directus": "^5.7.0",
|
"nuxt-directus": "^5.7.0",
|
||||||
"nuxt-openid-connect": "^0.8.1",
|
|
||||||
"v-phone-input": "^4.4.2",
|
"v-phone-input": "^4.4.2",
|
||||||
"vue": "latest",
|
"vue": "latest",
|
||||||
"vue-router": "latest",
|
"vue-router": "latest",
|
||||||
|
|
@ -8571,15 +8571,6 @@
|
||||||
"jiti": "bin/jiti.js"
|
"jiti": "bin/jiti.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jose": {
|
|
||||||
"version": "4.15.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz",
|
|
||||||
"integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/panva"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/js-levenshtein": {
|
"node_modules/js-levenshtein": {
|
||||||
"version": "1.1.6",
|
"version": "1.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
|
||||||
|
|
@ -8664,6 +8655,12 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/keycloak-js": {
|
||||||
|
"version": "26.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-26.2.0.tgz",
|
||||||
|
"integrity": "sha512-CrFcXTN+d6J0V/1v3Zpioys6qHNWE6yUzVVIsCUAmFn9H14GZ0vuYod+lt+SSpMgWGPuneDZBSGBAeLBFuqjsw==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/kleur": {
|
"node_modules/kleur": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
|
||||||
|
|
@ -9732,18 +9729,6 @@
|
||||||
"@nuxt/kit": "^3.0.0"
|
"@nuxt/kit": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/nuxt-openid-connect": {
|
|
||||||
"version": "0.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/nuxt-openid-connect/-/nuxt-openid-connect-0.8.1.tgz",
|
|
||||||
"integrity": "sha512-b/pMCZ4ZnY6VHqQ5clnjRnrz7OQ1wsydjcZIQ0c5VQq7BCgb5VBtp/9HETRqRArTjDiIqxc/Xu3hhddbHAfakA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@nuxt/kit": "^3.11.2",
|
|
||||||
"defu": "^6.0.0",
|
|
||||||
"openid-client": "^5.1.6",
|
|
||||||
"uuid": "^10.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/nypm": {
|
"node_modules/nypm": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/nypm/-/nypm-0.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/nypm/-/nypm-0.5.2.tgz",
|
||||||
|
|
@ -9764,15 +9749,6 @@
|
||||||
"node": "^14.16.0 || >=16.10.0"
|
"node": "^14.16.0 || >=16.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/object-hash": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.13.3",
|
"version": "1.13.3",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
|
||||||
|
|
@ -9831,15 +9807,6 @@
|
||||||
"integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==",
|
"integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/oidc-token-hash": {
|
|
||||||
"version": "5.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.1.0.tgz",
|
|
||||||
"integrity": "sha512-y0W+X7Ppo7oZX6eovsRkuzcSM40Bicg2JEJkDJ4irIt1wsYAP5MLSNv+QAogO8xivMffw/9OvV3um1pxXgt1uA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": "^10.13.0 || >=12.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/on-finished": {
|
"node_modules/on-finished": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||||
|
|
@ -9940,39 +9907,6 @@
|
||||||
"typescript": "^5.x"
|
"typescript": "^5.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/openid-client": {
|
|
||||||
"version": "5.7.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.1.tgz",
|
|
||||||
"integrity": "sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"jose": "^4.15.9",
|
|
||||||
"lru-cache": "^6.0.0",
|
|
||||||
"object-hash": "^2.2.0",
|
|
||||||
"oidc-token-hash": "^5.0.3"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/panva"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/openid-client/node_modules/lru-cache": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
|
||||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"yallist": "^4.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/openid-client/node_modules/yallist": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/own-keys": {
|
"node_modules/own-keys": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
|
||||||
|
|
@ -13614,19 +13548,6 @@
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/uuid": {
|
|
||||||
"version": "10.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
|
|
||||||
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
|
|
||||||
"funding": [
|
|
||||||
"https://github.com/sponsors/broofa",
|
|
||||||
"https://github.com/sponsors/ctavan"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"bin": {
|
|
||||||
"uuid": "dist/bin/uuid"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/v-phone-input": {
|
"node_modules/v-phone-input": {
|
||||||
"version": "4.4.2",
|
"version": "4.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/v-phone-input/-/v-phone-input-4.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/v-phone-input/-/v-phone-input-4.4.2.tgz",
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
"@vite-pwa/nuxt": "^0.10.6",
|
"@vite-pwa/nuxt": "^0.10.6",
|
||||||
"formidable": "^3.5.4",
|
"formidable": "^3.5.4",
|
||||||
"imap": "^0.8.19",
|
"imap": "^0.8.19",
|
||||||
|
"keycloak-js": "^26.2.0",
|
||||||
"libphonenumber-js": "^1.12.9",
|
"libphonenumber-js": "^1.12.9",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mailparser": "^3.7.3",
|
"mailparser": "^3.7.3",
|
||||||
|
|
@ -22,7 +23,6 @@
|
||||||
"nodemailer": "^7.0.3",
|
"nodemailer": "^7.0.3",
|
||||||
"nuxt": "^3.15.4",
|
"nuxt": "^3.15.4",
|
||||||
"nuxt-directus": "^5.7.0",
|
"nuxt-directus": "^5.7.0",
|
||||||
"nuxt-openid-connect": "^0.8.1",
|
|
||||||
"v-phone-input": "^4.4.2",
|
"v-phone-input": "^4.4.2",
|
||||||
"vue": "latest",
|
"vue": "latest",
|
||||||
"vue-router": "latest",
|
"vue-router": "latest",
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,8 @@ definePageMeta({
|
||||||
// Directus auth
|
// Directus auth
|
||||||
const { login } = useDirectusAuth();
|
const { login } = useDirectusAuth();
|
||||||
|
|
||||||
// OIDC auth for Keycloak
|
// Keycloak auth for SSO
|
||||||
const oidc = useOidc();
|
const keycloak = useKeycloak();
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const errorThrown = ref(false);
|
const errorThrown = ref(false);
|
||||||
|
|
@ -127,9 +127,9 @@ const passwordVisible = ref(false);
|
||||||
const valid = ref(false);
|
const valid = ref(false);
|
||||||
|
|
||||||
// Keycloak login function
|
// Keycloak login function
|
||||||
const loginWithKeycloak = () => {
|
const loginWithKeycloak = async () => {
|
||||||
// Redirect to dashboard after login
|
// Initialize and login with Keycloak
|
||||||
oidc.login('/dashboard');
|
await keycloak.login();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Directus login function
|
// Directus login function
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue