Files
hermione-fe/src/main.js
Andrea Terzani 443d0d83f7 before refactor
2025-12-12 16:37:28 +01:00

254 lines
8.6 KiB
JavaScript

import { createAuth } from '@websanova/vue-auth';
import driverAuthBearer from '@websanova/vue-auth/dist/drivers/auth/bearer.esm.js';
import driverHttpAxios from '@websanova/vue-auth/dist/drivers/http/axios.1.x.esm.js';
import driverRouterVueRouter from '@websanova/vue-auth/dist/drivers/router/vue-router.2.x.esm.js';
import axios from 'axios';
import { createPinia } from 'pinia';
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { AuthService } from './service/AuthService.js';
import { TokenRefreshManager } from './service/TokenRefreshManager.js';
import '@/assets/styles.scss';
import '@/assets/tailwind.css';
import BlockViewer from '@/components/BlockViewer.vue';
import { definePreset } from '@primevue/themes';
import Nora from '@primevue/themes/nora';
import { config } from 'md-editor-v3';
import PrimeVue from 'primevue/config';
import ConfirmationService from 'primevue/confirmationservice';
import ToastService from 'primevue/toastservice';
import { LoadingStore } from './stores/LoadingStore.js';
// Declare variables that will be used globally
let authInstance = null;
let tokenRefreshManager = null;
config({
editorConfig: {
renderDelay: 0,
zIndex: 200000000
}
});
var auth = createAuth({
plugins: {
http: axios,
router: router
},
drivers: {
http: driverHttpAxios,
auth: driverAuthBearer,
router: driverRouterVueRouter
},
options: {
notFoundRedirect: '/',
authRedirect: '/',
authRedirect: true, // niente redirect automatici
notFoundRedirect: false,
loginData: { url: '/api/auth/login', method: 'POST', redirect: '/home' },
logoutData: { url: '/api/auth/logout', redirect: '/auth/login' },
fetchData: { url: '/api/auth/fetch-user', method: 'GET', enabled: false },
refreshData: { url: '/api/auth/refresh-token', method: 'GET', enabled: true }
}
});
//axios.defaults.baseURL = import.meta.env.VITE_BACKEND_URL;
axios.defaults.baseURL = 'http://localhost:8081';
console.log(import.meta.env.VITE_BACKEND_URL);
const app = createApp(App);
const pinia = createPinia();
const preset = definePreset(Nora, {
semantic: {
primary: {
50: '{violet.50}',
100: '{violet.100}',
200: '{violet.200}',
300: '{violet.300}',
400: '{violet.400}',
500: '{violet.500}',
600: '{violet.600}',
700: '{violet.700}',
800: '{violet.800}',
900: '{violet.900}',
950: '{violet.950}'
},
colorScheme: {
light: {
surface: {
0: '#f3f3f3',
50: '{viva.50}',
100: '{viva.100}',
200: '{viva.200}',
300: '{viva.300}',
400: '{viva.400}',
500: '{viva.500}',
600: '{viva.600}',
700: '{viva.700}',
800: '{viva.800}',
900: '{viva.900}',
950: '{viva.950}'
},
formField: {
hoverBorderColor: '{primary.color}',
borderColor: '{primary.color}'
}
},
dark: {
surface: {
0: '#ffffff',
50: '{slate.50}',
100: '{slate.100}',
200: '{slate.200}',
300: '{slate.300}',
400: '{slate.400}',
500: '{slate.500}',
600: '{slate.600}',
700: '{slate.700}',
800: '{slate.800}',
900: '{slate.900}',
950: '{slate.950}'
},
formField: {
hoverBorderColor: '{primary.color}',
borderColor: '{primary.color}'
}
}
},
focusRing: {
width: '2px',
color: '{primary.color}',
offset: '1px'
}
}
});
app.use(pinia);
app.use(router);
app.use(PrimeVue, {
theme: {
preset: preset,
options: {
prefix: 'p',
darkModeSelector: '.app-dark',
cssLayer: false
}
}
});
app.use(ToastService);
app.use(ConfirmationService);
app.use(auth);
app.component('BlockViewer', BlockViewer);
app.mount('#app');
// Store auth instance for interceptor and token refresh manager after app is mounted
authInstance = app.config.globalProperties.$auth;
tokenRefreshManager = new TokenRefreshManager(authInstance);
// Start token refresh timer when user is authenticated
if (authInstance.check()) {
tokenRefreshManager.startRefreshTimer();
}
// Listen for successful login to start token refresh timer
window.addEventListener('auth-login-success', () => {
console.log('[Main] Login success event received, starting token refresh timer');
if (tokenRefreshManager) {
tokenRefreshManager.startRefreshTimer();
}
});
// Stop token refresh timer on logout
window.addEventListener('auth-logout', () => {
console.log('[Main] Logout event received, stopping token refresh timer');
if (tokenRefreshManager) {
tokenRefreshManager.stopRefreshTimer();
}
});
const loadingStore = LoadingStore();
axios.interceptors.request.use(
function (config) {
loadingStore.another_loading = true;
return config;
},
function (error) {
return Promise.reject(error);
}
);
axios.interceptors.response.use(
function (response) {
loadingStore.another_loading = false;
return response;
},
async function (error) {
loadingStore.another_loading = false;
// Don't handle auth-related URLs to prevent infinite loops
const isAuthUrl = error.config && (error.config.url.includes('/api/auth/') || error.config.url.includes('/msauth/'));
// Handle 403 errors by attempting token refresh (but not for auth URLs)
if (error.response && error.response.status === 403 && !isAuthUrl) {
console.log('[Interceptor] 403 error detected, attempting token refresh...');
// Check if we have an authenticated user and authInstance is available
if (authInstance && authInstance.check && authInstance.check()) {
try {
// Use our custom AuthService to refresh tokens (both MSAL and classic)
const refreshResult = await AuthService.refreshToken(authInstance);
if (refreshResult.success && refreshResult.token) {
console.log('[Interceptor] Token refresh successful, updating auth and retrying request...');
// Update the auth token
authInstance.token(null, refreshResult.token, false);
// Update the original request with new token
error.config.headers['Authorization'] = `Bearer ${refreshResult.token}`;
// Retry the original request
return axios.request(error.config);
} else {
console.error('[Interceptor] Token refresh failed:', refreshResult.error);
throw new Error(refreshResult.error);
}
} catch (refreshError) {
console.error('[Interceptor] Token refresh process failed:', refreshError);
// If refresh fails, logout and redirect to login
try {
// Stop token refresh timer
window.dispatchEvent(new CustomEvent('auth-logout'));
await AuthService.logout();
if (authInstance && authInstance.logout) {
authInstance.logout({
redirect: '/auth/login'
});
} else {
window.location.href = '/auth/login';
}
} catch (logoutError) {
console.error('[Interceptor] Logout failed:', logoutError);
// Force redirect to login
window.location.href = '/auth/login';
}
return Promise.reject(refreshError);
}
} else {
console.log('[Interceptor] No authenticated user for non-auth 403, ignoring...');
}
}
return Promise.reject(error);
}
);