Files
simrsx-fe/app/composables/useKeycloack.ts
2025-12-15 15:19:39 +07:00

121 lines
3.2 KiB
TypeScript

import Keycloak from "keycloak-js";
import { ref, computed, onBeforeMount } from "vue";
let kc: any | null = null;
const initialized = ref(false);
const authenticated = ref(false);
const token = ref<string | null>(null);
const profile = ref<any>(null);
export function useKeycloak() {
const config = useRuntimeConfig()
const initKeycloak = async (onLoad: "login-required" | "check-sso" = "check-sso") => {
if (kc) return kc;
kc = new Keycloak({
url: config.public.KEYCLOAK_URL,
realm: config.public.KEYCLOAK_REALM,
clientId: config.public.CLIENT_ID,
});
try {
const initOptions = {
onLoad,
checkLoginIframe: false as const,
promiseType: "native" as const,
pkceMethod: "S256" as const,
};
console.log(kc.url)
authenticated.value = await kc.init(initOptions);
initialized.value = true;
token.value = kc.token ?? null;
if (authenticated.value) {
try {
profile.value = await kc.loadUserProfile();
} catch (e) {
profile.value = null;
}
}
// automatically update token in background
kc.onTokenExpired = async () => {
try {
const refreshed = await kc.updateToken(30);
token.value = kc?.token ?? null;
if (!refreshed) {
// token not refreshed but still valid
}
} catch (err) {
console.warn("Failed to refresh token", err);
}
};
return kc;
} catch (err) {
console.log(authenticated)
console.error("Keycloak init xyz failed", err);
initialized.value = true;
authenticated.value = false;
return kc;
}
};
const loginSSO = (options?: Keycloak.KeycloakLoginOptions) => {
if (!kc) throw new Error("Keycloak not initialized");
return kc.login(options);
};
const logoutSSO = (redirectUri?: string) => {
if (!kc) throw new Error("Keycloak not initialized");
return kc.logout({ redirectUri });
};
const getToken = () => token.value;
const isAuthenticated = computed(() => authenticated.value);
const getProfile = () => profile.value;
// init on client automatically
onBeforeMount(() => {
// try check-sso silently
if (!initialized.value) initKeycloak("check-sso");
});
const apiErrors = ref<Record<string, string>>({})
const { login } = useUserStore()
const getResponse = async () => {
console.log("=================== onto login fes!!! ===================")
const params = {
token: token.value,
user: profile.value
}
const result = await xfetch('/api/v1/authentication/login-fes', 'POST', {
data: params,
})
if (result.success) {
const { data: rawdata, meta } = result.body
if (meta.status === 'verified') {
login(rawdata)
navigateTo('/')
}
} else {
if (result.errors) {
Object.entries(result.errors).forEach(
([field, errorInfo]: [string, any]) => (apiErrors.value[field] = errorInfo.message),
)
} else {
apiErrors.value.general = result.error?.message || result.message || 'Login failed'
}
}
}
return {
initKeycloak,
loginSSO,
logoutSSO,
getToken,
isAuthenticated,
getProfile,
getResponse,
};
}