Files
website/src/composables/useAuthUtils.ts
mrjvs f796bc00ec
Some checks failed
Build and Publish Docker Image / Build and Publish (amd64) (push) Has been cancelled
Build and Publish Docker Image / Build and Publish (arm64) (push) Has been cancelled
fix: fixed redirect to login
2026-08-15 19:01:25 +02:00

63 lines
1.6 KiB
TypeScript

export function getSafeRedirectUrl(input: string | null, baseUrl: string, allowedHosts: string[] = []): { url: string; external: boolean } | null {
const parsedBaseUrl = new URL(baseUrl);
if (!input) {
return null; // No or empty input
}
let url: URL | null = null;
try {
url = new URL(input, parsedBaseUrl);
} catch {
return null; // Invalid URL input
}
const isAllowedHost = allowedHosts.includes(url.host);
if (!isAllowedHost) {
return null; // Not in the allowed hosts
}
// If on the same host as the website, only return the path. For internal redirects
if (url.host === parsedBaseUrl.host) {
return {
url: url.pathname + url.search,
external: false
};
}
return {
url: url.toString(),
external: true
};
}
export function useAuthUtils() {
const authStore = useAuthStore();
const config = useRuntimeConfig();
const allowedRedirectHosts = computed(() => config.public.redirectHosts.split(' ').map(v => v.trim()).filter(v => v.length > 0));
return {
async safelyRedirectAfterLogin(inputUrl: string | null) {
const redirectUrl = getSafeRedirectUrl(inputUrl, config.public.baseUrl, allowedRedirectHosts.value);
if (!redirectUrl) {
await navigateTo('/account');
return;
}
await navigateTo(redirectUrl.url, {
external: redirectUrl.external
});
},
redirectToLogin(to?: string | undefined) {
const target = to ?? useRoute().fullPath;
return navigateTo({
path: '/account/login',
query: {
redirect: target
}
});
},
async logout() {
authStore.logout();
await navigateTo('/'); // Back to homepage
}
};
}