integrate login page wih api and keycloak

This commit is contained in:
Yusron alamsyah
2026-03-31 11:11:39 +07:00
parent acf491f8aa
commit d438fb0f5f
68 changed files with 1213 additions and 212 deletions
+89
View File
@@ -0,0 +1,89 @@
// composables/useAuth.ts
import { computed, ref } from 'vue';
import type { SessionData as UserSession, LogoutResponse } from '~/types/auth';
const sessionData = ref<UserSession | null>(null);
const isLoggedIn = ref(false);
const isLoading = ref(false);
const clearLocalAuthStorage = () => {
if (!process.client) return;
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
localStorage.removeItem('user-preferences');
localStorage.removeItem('app-state');
sessionStorage.clear();
};
export const useAuth = () => {
const fetchUserSession = async () => {
isLoading.value = true;
try {
const response = await $fetch<UserSession>('/api/auth/sessionUser', {
method: 'GET',
});
sessionData.value = response;
isLoggedIn.value = !!response;
} catch {
sessionData.value = null;
isLoggedIn.value = false;
} finally {
isLoading.value = false;
}
};
const logout = async (): Promise<void> => {
try {
await $fetch<LogoutResponse>('/api/auth/logout', {
method: 'POST',
});
} finally {
clearLocalAuthStorage();
sessionData.value = null;
isLoggedIn.value = false;
await navigateTo('/auth/login?logout=success');
}
};
const fullLogout = async (): Promise<void> => {
try {
const response = await $fetch<LogoutResponse>('/api/auth/logout', {
method: 'POST',
});
clearLocalAuthStorage();
sessionData.value = null;
isLoggedIn.value = false;
if (process.client && response?.success && response?.logoutUrl) {
window.location.href = response.logoutUrl;
return;
}
await navigateTo('/auth/login?logout=full');
} catch {
clearLocalAuthStorage();
sessionData.value = null;
isLoggedIn.value = false;
await navigateTo('/auth/login?logout=full');
}
};
const user = computed(() => sessionData.value?.user ?? null);
const userRoles = computed(() => sessionData.value?.user?.role ?? []);
return {
isLoggedIn,
isLoading,
sessionData,
user,
userRoles,
fetchUserSession,
logout,
fullLogout,
};
};
+49
View File
@@ -0,0 +1,49 @@
import { ref } from 'vue';
import api from '~/utils/api';
import type { AuthInfoResponse } from '~/types/auth';
const authInfo = ref<AuthInfoResponse | null>(null);
const isLoading = ref(false);
const errorMessage = ref<string | null>(null);
export const useAuthInfo = () => {
const fetchAuthInfo = async (accessToken: string) => {
if (!accessToken || !accessToken.trim()) {
throw new Error('accessToken is required');
}
isLoading.value = true;
errorMessage.value = null;
try {
const response = await api.get<AuthInfoResponse>('/api/v1/auth/info', {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
});
authInfo.value = response.data;
return response.data;
} catch (error) {
authInfo.value = null;
errorMessage.value = error instanceof Error ? error.message : 'Failed to fetch auth info';
throw error;
} finally {
isLoading.value = false;
}
};
const clearAuthInfo = () => {
authInfo.value = null;
errorMessage.value = null;
};
return {
authInfo,
isLoading,
errorMessage,
fetchAuthInfo,
clearAuthInfo,
};
};