Skip to content

Commit 7a4227a

Browse files
authored
fix: login redirects (#58)
- login redirects properly encode/decode - redirect back to login if user session gets cleared after logging in - remove unused middleware logic paths - fallback to a homepage redirect if a malicious external URL is used
1 parent acdebaf commit 7a4227a

4 files changed

Lines changed: 41 additions & 30 deletions

File tree

app/components/PageStandard.vue

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,27 @@ import type { NuxtError } from "nuxt/app";
1919
import type { PageStandardFragment } from "~~/shared/types/graphql";
2020
2121
const { slug } = defineProps<{ slug: string }>();
22-
const { query } = useRoute();
22+
const { query, path } = useRoute();
23+
const { clear } = useUserSession();
2324
24-
const { data, error } = useFetch<PageStandardFragment>("/api/cms/standard", {
25-
query: { slug, token: query.token || undefined },
26-
});
25+
const { data, error } = await useFetch<PageStandardFragment>(
26+
"/api/cms/standard",
27+
{
28+
query: { slug, token: query.token || undefined },
29+
},
30+
);
2731
2832
if (error.value) {
2933
const statusCode = (error.value as NuxtError).statusCode || 500;
30-
throw createError({
31-
statusCode,
32-
statusMessage: statusCode === 404 ? "Not Found" : "Something went wrong",
33-
});
34+
if (statusCode === 401) {
35+
clear();
36+
await navigateTo({ path: "/login", query: { redirect: path } });
37+
} else {
38+
throw createError({
39+
statusCode,
40+
statusMessage: statusCode === 404 ? "Not Found" : "Something went wrong",
41+
});
42+
}
3443
}
3544
3645
watch(

app/middleware/authenticated.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,13 @@ export default defineNuxtRouteMiddleware((to) => {
33

44
// Check if route is an admin route
55
if (to.path.startsWith("/admin")) {
6-
// Allow access to admin login page
7-
if (to.path === "/admin/login") {
8-
// If already logged in and is admin, redirect to dashboard
9-
if (loggedIn.value && user.value?.permission === "admin") {
10-
return navigateTo("/admin/dashboard");
11-
}
12-
return;
13-
}
14-
156
// For all other admin routes, require authentication and admin status
167
if (!loggedIn.value || user.value?.permission !== "admin") {
178
return navigateTo("/admin/login");
189
}
1910
return;
2011
}
2112

22-
// For non-admin routes: check site password authentication
23-
// Skip the login page itself
24-
if (to.path === "/login") {
25-
// If already logged in with site password, redirect to home
26-
if (loggedIn.value) {
27-
const redirect = (to.query.redirect as string) || "/";
28-
return navigateTo(redirect);
29-
}
30-
return;
31-
}
32-
3313
// All other pages require site password authentication
3414
if (!loggedIn.value) {
3515
const isRoot = to.fullPath === "/";

app/pages/login.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,13 @@ const isLoading = shallowRef(false);
4848
const passwordRef = ref<InstanceType<typeof FormInput> | null>(null);
4949
5050
const proceedToSite = async () => {
51-
const redirect = (route.query.redirect as string) || "/";
52-
await navigateTo(redirect, { replace: true });
51+
const redirect = getRedirectUrl(route.query.redirect);
52+
try {
53+
await navigateTo(redirect, { replace: true });
54+
} catch {
55+
// If the redirect URL is invalid or malicious, fallback to home page
56+
await navigateTo("/", { replace: true });
57+
}
5358
};
5459
5560
// Redirect if already logged in

app/utils/url.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { LocationQueryValue } from "vue-router";
2+
3+
export const getRedirectUrl = (
4+
to: LocationQueryValue | LocationQueryValue[] | undefined,
5+
) => {
6+
const parsedTo = Array.isArray(to) ? to[0] : to;
7+
8+
if (!parsedTo) {
9+
return "/";
10+
}
11+
12+
try {
13+
return decodeURIComponent(parsedTo);
14+
} catch {
15+
return "/";
16+
}
17+
};

0 commit comments

Comments
 (0)