auth: smart login/logout redirect back to original page
Some checks failed
CI / update (push) Failing after 0s
Some checks failed
CI / update (push) Failing after 0s
Login link now includes callbackUrl for the current page. Logout redirects intelligently: stays on public pages, falls back to the recipe detail for /edit/[name], to the recipe root for auth-only sub-routes (add, favorites, to-try, admin), and to / for cospend.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
|
||||||
let { user, recipeLang = 'rezepte', lang = 'de' } = $props();
|
let { user, recipeLang = 'rezepte', lang = 'de' } = $props();
|
||||||
|
|
||||||
@@ -18,6 +19,29 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function getLogoutCallbackUrl(pathname: string): string {
|
||||||
|
// Cospend has no public equivalent
|
||||||
|
if (pathname.startsWith('/cospend')) return '/';
|
||||||
|
|
||||||
|
// Match /rezepte or /recipes prefix
|
||||||
|
const m = pathname.match(/^\/(rezepte|recipes)(\/.*)?$/);
|
||||||
|
if (m) {
|
||||||
|
const base = `/${m[1]}`;
|
||||||
|
const rest = m[2] ?? '';
|
||||||
|
|
||||||
|
// /edit/[name] → the recipe detail page
|
||||||
|
const editMatch = rest.match(/^\/edit\/(.+)$/);
|
||||||
|
if (editMatch) return `${base}/${editMatch[1]}`;
|
||||||
|
|
||||||
|
// Auth-only sub-routes → recipe root
|
||||||
|
if (/^\/(add|favorites|to-try|admin|administration)(\/|$)/.test(rest))
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public page: stay here
|
||||||
|
return pathname;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
/* (A) SPEECH BOX */
|
/* (A) SPEECH BOX */
|
||||||
@@ -155,10 +179,10 @@ h2 + p{
|
|||||||
<li><a href="/{recipeLang}/administration">Administration</a></li>
|
<li><a href="/{recipeLang}/administration">Administration</a></li>
|
||||||
{/if}
|
{/if}
|
||||||
<li><a href="https://sso.bocken.org/if/user/#/settings" >Einstellungen</a></li>
|
<li><a href="https://sso.bocken.org/if/user/#/settings" >Einstellungen</a></li>
|
||||||
<li><a href="/logout" >Log Out</a></li>
|
<li><a href="/logout?callbackUrl={encodeURIComponent(getLogoutCallbackUrl($page.url.pathname))}">Log Out</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
{:else}
|
{:else}
|
||||||
<a class=entry href=/login>Login</a>
|
<a class=entry href="/login?callbackUrl={encodeURIComponent($page.url.pathname + $page.url.search)}">Login</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ export const load: PageServerLoad = async ({ fetch, locals, params }) => {
|
|||||||
const session = await locals.auth();
|
const session = await locals.auth();
|
||||||
|
|
||||||
if (!session?.user?.nickname) {
|
if (!session?.user?.nickname) {
|
||||||
throw redirect(302, `/${params.recipeLang}`);
|
const callbackUrl = encodeURIComponent(`/${params.recipeLang}/favorites`);
|
||||||
|
throw redirect(302, `/login?callbackUrl=${callbackUrl}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -6,7 +6,12 @@ import { dbConnect } from '$utils/db';
|
|||||||
export const load: PageServerLoad = async ({ locals, params }) => {
|
export const load: PageServerLoad = async ({ locals, params }) => {
|
||||||
const session = await locals.auth();
|
const session = await locals.auth();
|
||||||
|
|
||||||
if (!session?.user?.groups?.includes('rezepte_users')) {
|
if (!session?.user) {
|
||||||
|
const callbackUrl = encodeURIComponent(`/${params.recipeLang}/to-try`);
|
||||||
|
throw redirect(302, `/login?callbackUrl=${callbackUrl}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!session.user.groups?.includes('rezepte_users')) {
|
||||||
throw redirect(302, `/${params.recipeLang}`);
|
throw redirect(302, `/${params.recipeLang}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user