Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions app/components/PageStandard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,27 @@ import type { NuxtError } from "nuxt/app";
import type { PageStandardFragment } from "~~/shared/types/graphql";

const { slug } = defineProps<{ slug: string }>();
const { query } = useRoute();
const { query, path } = useRoute();
const { clear } = useUserSession();

const { data, error } = useFetch<PageStandardFragment>("/api/cms/standard", {
query: { slug, token: query.token || undefined },
});
const { data, error } = await useFetch<PageStandardFragment>(
"/api/cms/standard",
{
query: { slug, token: query.token || undefined },
},
);

if (error.value) {
const statusCode = (error.value as NuxtError).statusCode || 500;
throw createError({
statusCode,
statusMessage: statusCode === 404 ? "Not Found" : "Something went wrong",
});
if (statusCode === 401) {
clear();
await navigateTo({ path: "/login", query: { redirect: path } });
} else {
Comment thread
ben-basten marked this conversation as resolved.
throw createError({
statusCode,
statusMessage: statusCode === 404 ? "Not Found" : "Something went wrong",
});
}
}

watch(
Expand Down
20 changes: 0 additions & 20 deletions app/middleware/authenticated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,13 @@ export default defineNuxtRouteMiddleware((to) => {

// Check if route is an admin route
if (to.path.startsWith("/admin")) {
// Allow access to admin login page
if (to.path === "/admin/login") {
// If already logged in and is admin, redirect to dashboard
if (loggedIn.value && user.value?.permission === "admin") {
return navigateTo("/admin/dashboard");
}
return;
}

// For all other admin routes, require authentication and admin status
if (!loggedIn.value || user.value?.permission !== "admin") {
return navigateTo("/admin/login");
}
return;
}

// For non-admin routes: check site password authentication
// Skip the login page itself
if (to.path === "/login") {
// If already logged in with site password, redirect to home
if (loggedIn.value) {
const redirect = (to.query.redirect as string) || "/";
return navigateTo(redirect);
}
return;
}

// All other pages require site password authentication
if (!loggedIn.value) {
const isRoot = to.fullPath === "/";
Expand Down
9 changes: 7 additions & 2 deletions app/pages/login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,13 @@ const isLoading = shallowRef(false);
const passwordRef = ref<InstanceType<typeof FormInput> | null>(null);

const proceedToSite = async () => {
const redirect = (route.query.redirect as string) || "/";
await navigateTo(redirect, { replace: true });
const redirect = getRedirectUrl(route.query.redirect);
try {
await navigateTo(redirect, { replace: true });
} catch {
// If the redirect URL is invalid or malicious, fallback to home page
await navigateTo("/", { replace: true });
}
};

// Redirect if already logged in
Expand Down
17 changes: 17 additions & 0 deletions app/utils/url.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { LocationQueryValue } from "vue-router";

export const getRedirectUrl = (
to: LocationQueryValue | LocationQueryValue[] | undefined,
) => {
const parsedTo = Array.isArray(to) ? to[0] : to;

if (!parsedTo) {
return "/";
}

try {
return decodeURIComponent(parsedTo);
} catch {
return "/";
}
Comment thread
ben-basten marked this conversation as resolved.
};
Loading